Introducción
Aunque sean estructuras sencillas, la vida de un virus en absoluto lo es. No puede ser demasiado letal ni demasiado inocente , tiene que aprender a vivir con su hospedador sin exprimirlo mucho ni poco, en un juego evolutivo con múltiples facetas e implicaciones..
Lo que sigue a continuación no es más que un simple ejercicio en el que se pone a prueba el poder de predicción de unas simples ecuaciones y un juego con sencillas reglas. Sus implicaciones, por tanto, son más heurísticas que aplicables. Cualquier modelo que verdaderamente pueda ser predictivo para el caso que todos tenemos en mente debe considerar muchos aspectos secundarios que aquí se obvian.
No obstante, los resultados son lo bastante interesantes como para hacernos pensar sobre detalles aparentemente triviales que después se manifiestan de forma sorprendente.
Matemática de una epidemia
Una epidemia es el fenómeno demográfico provocado por la dispersión de una enfermedad contagiosa en una población. La enfermedad va saltando de individuo en individuo a través de un vector, un virus en este caso. La epidemia es la dinámica temporal que manifiesta el número de infectados, que suele comenzar de una manera explosiva (exponencial, propiamente hablando) para llegar a un pico y luego disminuir hasta que desaparece la enfermedad de la población.
Ecuaciones
El modelo más sencillo surge a partir de los siguientes axiomas:
Cualquier individuo susceptible puede contraer la enfermedad con cierta probabilidad en un plazo determinado.
Esta probabilidad aumenta proporcionalmente al número de infectados.
Al cabo de cierto tiempo la enfermedad cesa en el infectado, bien con su inmunización o con su muerte, con el efecto neto de sacarlo de la población susceptible o infectada.
Con estas premisas de partida, el par de sesudos matemáticos ingleses Kermack y Kendrick a partir de unos trabajos previos muy enrevesados del teniente coronel Ross y (probablemente) su querida madame Hudson, desarrollaron hace un siglo un completa teoría matemática que, simplificada al considerar tasas constantes y una población suficientemente grande, se puede resumir en la siguiente ecuación:
\[\begin{align}
cambio\;en\;infectados =& \;contagios - recuperaciones \\[7pt]
\frac{dI}{dt} =& \beta S I - \gamma I
\end{align}\]
El término \(\beta S I\) representa el número de nuevos contagios por unidad de tiempo, siendo \(S\) e \(I\) , respectivamente, el número de susceptibles e infectados en la población; mientras que \(\beta\) es un coeficiente de contagio que aúna en un solo parámetro las propiedades contagiosas de la enfermedad y los hábitos sociales de la población: cuanto mayor es, más fácilmente se contagia la enfermedad.
Por otro lado, \(\gamma I\) representa la retirada de individuos infectados (bien porque se recuperan volviéndose inmunes, bien porque pasan a mejor vida; el caso es que ya no juegan ). El coeficiente \(\gamma\) está relacionado con la duración de la enfermedad, en particular, con el tiempo que el individuo es contagioso, como veremos con detalle dentro de un rato.
Si incluimos la dinámica de los susceptibles \(S\) y los retirados \(R\) , tendremos esta terna de ecuaciones:
\[\begin{align}
\frac{dS}{dt} &= - \beta S I \\[7pt]
\frac{dI}{dt} &= \beta S I - \gamma I \\[7pt]
\frac{dR}{dt} &= \gamma I
\end{align}\]
Ejemplo académico
Para comprender mejor el sentido de ecuaciones y parámetros, veamos cómo aparece el modelo a partir de unas observaciones naturales y más intuitivas. Imaginemos que, en cierta población con 50.000 habitantes susceptibles ocurre una epidemia y se ha comprobado que:
Un infectado contagia la enfermedad a 3 personas, en promedio.
La enfermedad en fase contagiosa dura 1 semana, en promedio.
Cálculo de \(\beta\)
Vamos con la primera observación. ¿Podemos deducir el valor de \(\beta\) ? A ver…
Un infectado contagia a 3 susceptibles; como lo puede hacer mientras dura su fase contagiosa (7 días), cada día contagiará a \(\frac{3}{7}\) individuos.
Como hay \(I\) infectados, el número de nuevos contagios diarios será \(\frac{3}{7}I\) .
¿Y cómo metemos \(S\) ? Veamos… La primera observación es claramente incompleta, le falta «…al principio de la epidemia»: está claro que la probabilidad de que un infectado se lo pegue a un susceptible es mucho mayor al principio de la epidemia (cuando \(S\) es grande) que al final (cuando \(S\) es menor), por pura ley de acción de masas . Esto significa que \(\frac{3}{7}\) es justamente \(\beta S_0\) , siendo \(S_0\) la población susceptible inicial (50.000). Ya lo tenemos:
\[\beta = \frac{3}{7}·\frac{1}{50000} = 8.57 \cdot 10^{-6} \; (\text{individuos}^{-1}\text{·día}^{-1})\]
Cálculo de \(\gamma\)
Vamos con la segunda. ¿Podemos deducir el valor de \(\gamma\) ? Para verlo más fácilmente, supongamos que tenemos 35 infectados; ¿cuántos se recuperarán en un día? La figura tal vez ayude:
Figura 1. Significado de \(\gamma\) . Como la duración de la enfermedad es de una semana, cuando pase 1 día se recuperarán 5 de los 35 infectados, es decir \({1}/{7}\) que es justo el valor de \(\gamma\) . Así que \(\gamma\) es, intuitivamente, el inverso de la duración de la enfermedad.
En principio, porque ya veremos más adelante. El razonamiento anterior asume que tenemos infectados recientes y veteranos en la misma proporción (los puntitos rojos se distribuyen homogéneamente en el plazo de convalecencia). No es difícil demostrar que esta premisa se cumple siempre en un estado estacionario pero, como la epidemia cursa en forma de onda, esto supondrá un problema que solucionaremos más adelante.
Dinámica
Ya tenemos todo. Si integramos las ecuaciones veremos el aspecto gráfico de la epidemia:
{
# INTEGRACIÓN DE LAS ECUACIONES S.I.R.
#---- tiempo final
tiempo_final <- 100
t <- seq (from = 1 , to = tiempo_final)
#---- condiciones iniciales y valores de coeficientes
S <- numeric ()
S[1 ] <- 50000 # susceptibles iniciales
I <- numeric ()
I[1 ] <- 1 # infectados iniciales
R <- numeric ()
R[1 ] <- 0 # retirados iniciales
beta <- 8.57E-6
gama <- 1 / 7
#---- bucle integración Euler
for (i in 1 : (length (t)- 1 )){
contagios <- beta* S[i]* I[i]
retirados <- gama* I[i]
S[i+ 1 ] <- S[i] - contagios
I[i+ 1 ] <- I[i] + (contagios - retirados)
R[i+ 1 ] <- R[i] + retirados
}
#---- gráfico
plot (t, S, ylim = c (0 , 50000 ), type = "l" , col = "green" , lwd = 2 ,
xlab = "TIEMPO (días)" , ylab = "INDIVIDUOS" )
lines (t, R, col = "orange" , lwd = 2 )
lines (t, I, col = "red" , lwd = 2 )
legend (0 , 50000 , c ("S" ,"I" ,"R" ), lwd = 2 , col = c ("green" , "red" , "orange" ), cex = 0.8 , bty = "n" )
}
Figura 2. Dinámica de una epidemia. La línea roja representa la epidemia, propiamente dicha. Puede observarse el inicio exponencial, el pico y la ulterior decaída, fases típicas en toda epidemia. Ojo a la línea verde: no todos los susceptibles deben pasar la enfermedad antes de que cese la epidemia.
Características de la dinámica epidémica
En la Figura 2 podemos apreciar las características dinámicas de toda epidemia: el inicio exponencial, el pico de infectados y el descenso final hasta la desaparición de la enfermedad en la población. Un aspecto interesante es que la epidemia puede (aunque no siempre) acabar antes de que todos los susceptibles pasen la enfermedad.
Otra característica importante es la asimetría de la curva: el inicio es mucho más empinado y el descenso más lento. Esto ocurre porque el contagio depende del cuadrado de los individuos mientras que la recuperación es función lineal.
Efecto de la densidad de población
El tamaño de la población también es un factor crítico. Podemos verlo mejor si expresamos los infectados en % de la población y hacemos varias simulaciones con distintas densidades de población, por ejemplo con 400.000, 200.000, 100.000, 25.000 y 12.000 almas:
Figura 3. Efecto de la densidad de población. La misma enfermedad desencadena distintos tipos de epidemia dependiendo del tamaño de la población susceptible: cuanto mayor es la población, más rápidamente se desencadena la epidemia, mayor porcentaje de la población se afecta y antes acaba el proceso. Pero… ¿qué ocurre con la de 12.000 habitantes?
Efectivamente, cuanto mayor es la población, más devastadora es la epidemia. Los efectos en poblaciones menores son cada vez más suaves, llegando al extremo, en la ciudad con 12.000 habitantes, de ni siquiera producirse la epidemia, a pesar de tratarse de la misma enfermedad y el mismo tipo costumbres sociales. ¿Por qué?
La mayor virulencia en poblaciones grandes podemos comprenderla intuitivamente: si un infectado contagiaba a 3 personas en una ciudad de 50.000 individuos, entonces, en una ciudad de 400.000 habitantes (8 veces más poblada) contagiará a 24 (8 veces más) y, por tanto, la velocidad de propagación será 8 veces mayor que en la ciudad de 50.000 almas.
El factor \(R_0\)
Al factor por el que se multiplica la infección (o número de individuos a los que contagia un infectado) se denomina \(R_0\) y vemos que es directamente proporcional a la densidad de población. Podemos calcular su valor sin necesidad de acudir a las diferenciales: al invertir el razonamiento mediante el que calculamos \(\beta\) y \(\gamma\) vemos que
\[R_0 = \frac{\beta S}{\gamma}\]
Ya tenemos su valor para la ciudad de 50.000 personas (era uno de los axiomas) y hemos hecho el cálculo para la población de 400.000 habitantes. Por curiosidad, apliquémoslo a las otras poblaciones:
400.000
24
200.000
12
100.000
6
50.000
3
25.000
1.5
12.000
0.75
¡Ah migo! En la última línea tenemos la explicación del fracaso de la epidemia en la ciudad pequeña: si un infectado solo es capaz de transmitir la enfermedad a 3/4 de persona, está claro que la epidemia no se producirá. Para que explote la epidemia, \(R_0\) debe ser mayor que 1.
Como depende directamente de \(S\) y éstos van siempre disminuyendo, el factor \(R_0\) también va disminuyendo desde el inicio de la epidemia. Veámoslo en el primer gráfico:
Figura 4. Evolución de \(R_0\) . El mismo gráfico de antes (50.000 susceptibles), pero ahora con el valor de \(R_0\) superpuesto. Su curva es idéntica a la de S, de hecho, es la misma multiplicada por \({\beta}/{\gamma}\) . Observa que, justo cuando \(R_0\) cruza el umbral de 1, la epidemia alcanza su pico y comienza a declinar.
Ejemplo real
El inicio de la epidemia de COVID en la Costa del Sol nos da un ejemplo, tan ilustrativo como triste, de estas simple matemáticas. Las primeras semanas de propagación de la enfermedad ocurrieron con esta cifras oficiales:
27/2/20
1
28/2/20
4
29/2/20
6
1/3/20
6
2/3/20
6
3/3/20
7
4/3/20
7
5/3/20
9
6/3/20
18
7/3/20
22
8/3/20
27
9/3/20
42
10/3/20
59
11/3/20
77
12/3/20
97
13/3/20
128
14/3/20
180
Figura 5. Primeras semanas de la COVID en la Costa del Sol. El aumento de infectados se produjo de forma exponencial.
Cálculo de los parámetros en Málaga
Veamos si podemos calcular los parámetros de la epidemia. El problema es muy interesante, matemáticamente hablando, pues consiste en el ajuste de una función que no tiene una expresión analítica explícita, pues resulta de la integración numérica de dos ecuaciones diferenciales. Dejo un frente abierto, intentando ajustar tanto \(\beta\) y \(\gamma\) como \(S_0\) de forma independiente, porque ahora el objetivo principal es más evolutivo que matemático. No obstante, con un poco de habilidad se puede simplificar el asunto, si podemos estimar el valor de \(S_0\) y \(\gamma\) independientemente de los datos.
Valor de \(S_0\)
Propiamente dicho, no es un coeficiente, pero sí un parámetro del modelo que debemos ajustar. Dado que el foco principal se localizó en toda la Costa del Sol (1.400.000 habitantes) y esta zona muestra propiedades de movilidad y costumbres muy homogéneas, parece acertado empezar con este valor.
Valor de \(\gamma\)
La duración total de la enfermedad es muy indefinida, va desde los 24 a los 57 días, según las fuentes de donde proceda la información. No obstante, dado que en Málaga ya se aislaban a las personas con los primeros síntomas, para nuestro cálculo solo tendremos en cuenta el tiempo que el recién contagiado circuló libremente sin mostrar síntomas pero siendo capaz de contagiar a otros, un periodo que puede ser de unas dos semanas. Tomaremos un valor de 15 días y luego calcularemos la incertidumbre del resultado con respecto a este dato, si es menester. Así, tomaremos un valor de \(\lambda = 0.07 \text{ días}^{-1}\) .
Valor de \(\beta\)
La ecuación central del modelo se puede escribir de esta forma:
\[\frac{dI}{dt} = (\beta S - \gamma) I\]
como aún aparece \(S\) en la expresión, su ajuste sigue requiriendo el método más sofisticado que tal vez abordemos en otra ocasión. No obstante, en aquel tiempo el número de infectados era muy pequeño (en comparación con \(S_0\) ) y podemos asumir que \(S\) es prácticamente constante en estos primeros compases, de manera que:
\[\frac{dI}{dt} \approx (\beta S_0 - \gamma) I\]
expresión que tiene integral inmediata y da la siguiente ecuación:
\[I = I_0 e^{(\beta S_0 - \gamma) t}\]
cuyo ajuste es inmediato por linealización. Sin embargo, para evitar el sesgo que esto provoca sobre los números más grandes, vamos a ajustar la expresión directamente por optimización:
{
#---- datos reales
I_real <- c (1 ,4 ,6 ,6 ,6 ,7 ,7 ,9 ,18 ,22 ,27 ,42 ,59 ,77 ,97 ,128 ,180 )
n <- length (I_real)
t_real <- seq (1 : n)
plot (t_real, I_real, xlab = "TIEMPO (días)" , ylab = "INFECTADOS" )
#---- parámetros estimados
S0 <- 1400000
gama <- 0.07
#---- definir la suma de diferencias cuadraticas como función
SDC <- function (dat, par) {
I <- par[1 ]* exp ((par[2 ]* S0 - gama)* t_real)
with (dat, sum ((I_real - I)^ 2 ))
}
#---- buscar los parámetros que la minimizan
datos <- data.frame (t_real,I_real)
resultado <- optim (par = c (1 , 1E-7 ), SDC, dat = datos)
I0 <- resultado$ par[1 ]
beta <- resultado$ par[2 ]
#---- gráfico de la nueva curva ajustada
t <- seq (0 , 20 , 0.1 )
I <- I0* exp ((beta* S0 - gama)* t)
lines (t,I, type = "l" , col = "red" , lwd = 2 )
#---- cálculo del coeficiente de determinación de la nueva curva
I_aj <- I0* exp ((beta* S0 - gama)* t_real)
R2curva <- 1 - sum ((I_real - I_aj)^ 2 )/ ((n-1 )* var (I_real))
text (12 ,150 ,bquote (R^ 2 : .(R2curva)))
#---- información sobre beta e I0
text (5 ,150 ,bquote (beta: .(beta)))
text (5 ,130 ,bquote (I_0: .(I0)))
}
Figura 6. Ajuste de \(\beta\) . A pesar de haber estimado dos parámetros y ajustado el tercero, este simple modelo es capaz de explicar más del 99% de la varianza de los datos (\(R^2 = 0.997\) ) y nos da un valor de \(\beta =2.64·10^{-7}\) individuos⁻¹ día⁻¹.
En este modelo ajustado, tenemos un valor de
\[R_0 = \frac{\beta S_0}{\gamma} = \frac{2.64·10^{-7} · 1400000}{0.07} = 5.28\]
que coincide con los cálculos hechos por modelos más sofisticados y está en concordancia con los valores de \(R_0\) determinados inicialmente en China y, durante bastante más tiempo, en Italia.
Como curiosidad
De esta sencilla aproximación se puede deducir una conclusión de interés epidemiológico: para reducir el \(R_0\) de la COVID por debajo de \(1\) , dado que es muy difícil acelerar \(\gamma\) , se puede disminuir \(S\) (con vacunas) o reducir \(\beta\) (con restricciones de movilidad). Según el valor calculado arriba, bastaría con dividir algunos de estos dos elementos entre \(5.3\) , esto es, en un 82 % aproximadamente. Esto significa vacunar al 82 % de la población susceptible, o bien, limitar nuestros contactos a 1 de cada 6 personas con las que tratamos habitualmente. Curiosamente, con solo los datos de las primeras semanas y un sencillo análisis, hemos alcanzado las mismas conclusiones que ahora guían la lucha contra esta epidemia… ¡Seguro que ha sido casualidad!
Epidemia con reinfección
Cuando los recuperados pierden la inmunidad y se vuelven suceptibles al cabo de cierto tiempo, aparece una dinámica cíclica conocida como olas . Esto ocurre porque se introduce un nuevo elemento en las ecuaciones que las convierte en un oscilador amortiguado:
\[\begin{align}
\frac{dS}{dt} &= \alpha R - \beta S I \\[7pt]
\frac{dI}{dt} &= \beta S I - \gamma I \\[7pt]
\frac{dR}{dt} &= \gamma I - \alpha R
\end{align}\]
El nuevo coeficiente \(\alpha\) es inversamente proporcional al tiempo que dura la inmunidad de un recuperado (ya no pueden ser muertos, claro está).
Veamos la dinámica del primer ejemplo, suponiendo que la inmunidad dura 20 semanas (\(\alpha = 1/140\) días⁻¹)
Figura 7. Epidemia con reinfección. Cuando los recuperados pierden la inmunidad se producen oleadas de infectados hasta que cesa la epidemia. La distancia entre los picos de estas olas y su intensidad son proporcionales a la duración de la inmunidad. Los coeficientes son los mismos de la Figura 2, más una pérdida de inmunidad a los 140 días.
También se podría añadir una tasa de mortalidad asociada con la enfermedad, para que el asunto fuese más realista, aunque el interés matemático es mínimo pues solo se manifiesta en una caída exponencial de los recuperados y la dinámica oscilante seguiría siendo prácticamente la misma.
Modelo basado en individuos
Lo de antes era solo para recordar lo básico del asunto. Aquí empieza lo interesante.
Cuando se afronta el fenómeno epidémico desde la mecánica basada en individuos se disfruta de unos axiomas más intuitivos:
Los individuos se mueven al azar por su pueblo.
Cuando un infectado contacta con un susceptible lo puede contagiar con una probabilidad \(p\) .
Al cabo de cierto tiempo, el infectado se recupera y ya no contagia más.
Aquí tenemos propiedades individuales, en vez de las colectivas del modelo diferencial. No nos enrollemos más y veamos la película del movimiento individual y la transmisión de la enfermedad:
Vídeo 1. Dinámica espacial de la epidemia. Los puntos rojos representan a los infectados (como se esperaba) que, cuando entran en contacto con los susceptibles (verdes) los infectan con cierta probabilidad. Al cabo de algunos días, los infectados se recuperan (negros).
Figura 8. Simulación basada en individuos. Con los titubeos debidos al azar, el patrón de la epidemia aparece claramente.
Aquí debajo el código:
{
# MODELO S.I.R. BASADO EN INDIVIDUOS
# Modelo básico para explicar el desarrollo de una epidemia
# (sin vídeo)
#---- tiempo final y tamaño del pueblo
tiempo_final <- 150
xmax <- 60 # ancho del pueblo (desde x = 1 hasta x = 100)
ymax <- 60 # largo " " (desde y = 1 hasta y = 100)
XY <- matrix (0L, xmax, ymax) # el pueblo, propiamente dicho
#---- variables
St <- integer ()
It <- integer () # para guardar los valores de S, I, R a cada tiempo
Rt <- integer ()
x <- integer () # posición x de los individuos
y <- integer () # " y " "
estado <- integer () # estado del individuo S:0 I:1 R:2
conval <- integer () # tiempo que lleva de convalecencia
#---- coeficientes y demás
p <- 0.9 # probabilidad de contagio
d <- 15 # duración de la enfermedad
mov <- c (- 1 , 0 , 1 ) # movimiento (una casilla pacalao)
pmv <- c (0.4 , 0.2 , 0.4 ) # probabilidad de moverse en cada dirección XY
#---- condiciones iniciales
N <- 1000 # número total de individuos
S <- N - 1 # susceptibles iniciales
I <- 1 # infectados "
R <- 0 # retirados "
St[1 ] <- S
It[1 ] <- I
Rt[1 ] <- R
# Localizar a los individuos
for (i in 1 : N){
x[i] <- floor (xmax* runif (1 ) + 1 ) # pensando en C...
y[i] <- floor (ymax* runif (1 ) + 1 )
estado[i] <- 0
XY[x[i], y[i]] <- i # localizar al último en llegar
}
# infectados
for (i in 1 : I){
x[i] <- floor (xmax* 0.5 + 1 )
y[i] <- floor (ymax* 0.5 + 1 )
estado[i] <- 1
XY[x[i], y[i]] <- i
estado[i] <- 1
conval[i] <- 0
}
#---- BUCLE DEL TIEMPO
for (t in 2 : tiempo_final){
XY1 <- XY # para hacer las operaciones sincronizadas
XY[] <- 0L # borrar la matriz
#---- bucle de los individuos
for (i in 1 : N){
# comprobar convalecencia
if (estado[i] == 1 ) {# solo para infectados
conval[i] <- conval[i] + 1
if (conval[i] > d) {# se recupera
estado[i] <- 2
I <- I - 1
R <- R + 1
}
}
# movimiento al azar
dx <- sample (mov, size = 1 , prob = pmv)
dy <- sample (mov, size = 1 , prob = pmv)
x[i] <- x[i] + dx
y[i] <- y[i] + dy
if (x[i] > xmax) {x[i] <- 1 } # por si se sale por los lados
if (x[i] < 1 ) {x[i] <- xmax}
if (y[i] > ymax) {y[i] <- 1 } # por si se sale por arriba/abajo
if (y[i] < 1 ) {y[i] <- ymax}
# detectar encuentro
o <- XY1[x[i], y[i]]
if (o > 0 ) {
if (o != i) { # se ha encontrado con otro
# se lo pego
if ((estado[i] == 1 ) & (estado[o] == 0 )){
if (runif (1 ) < p){
estado[o] <- 1
conval[o] <- 0
I <- I + 1
S <- S - 1
}
}
# me lo pega
if ((estado[o] == 1 ) & (estado[i] == 0 )){
if (runif (1 ) < p){
estado[i] <- 1
conval[i] <- 0
I <- I + 1
S <- S - 1
}
}
}
}
XY[x[i], y[i]] <- i # actualizar localización
}
St[t] <- S
It[t] <- I # guardar valores
Rt[t] <- R
}
#---- gráfico final
plot (St, type = "l" , lwd = 2 , col = "green" , ylim = c (0 ,N), xlab = "Tiempo" , ylab = "Individuos" )
lines (It, lwd = 2 , col = "red" )
lines (Rt, lwd = 2 )
legend (0 , N/ 2 , c ("S" , "I" , "R" ), lty = c (1 , 1 , 1 ), lwd = c (2 , 2 , 2 ), col = c (3 , 2 , 1 ), bty = "n" )
}
No me convence mucho el asunto de las matrices, porque el último en llegar al sitio es el que marca las propiedades. Vamos a dejarlo así por el momento, posiblemente no tenga mucha importancia en pueblos enrarecidos, pero la mosca está en la oreja.
Veamos el promedio de 100 simulaciones
Figura 9. Promedio de 100 simulaciones. Se parece al modelo diferencial peeerooo…
El inicio de la epidemia es demasiado lineal. Podría tratarse de:
Explicación sesuda: Aunque haya muchos susceptibles, cada infectado solo puede acceder a los que están más cerca de él, que es una cantidad constante. Esto se traduce en un frente de llama que avanza sobre un mar se susceptibles dejando tras sí un bosque de recuperados.
Artefacto: Al usar la misma matriz para todos los individuos, pueden enmascararse infectados por solapamiento con recuperados. Esto se podría evitar con matrices independientes para \(S\) e \(I\) y, ya puestos, también para \(R\) .
Antes de ponerme con las matrices independientes, confirmemos que se trata del efecto frente de llama. Para evitarlo, creo que basta con disminuir la probabilidad de contagio y aumentar la duración de la enfermedad. Veamos:
Figura 10. Evitar el frente de llama. Efectivamente, cuando se reduce la probabilidad de contagio y aumenta el tiempo de convalecencia desaparece el efecto frente de llama . Ahora lo sospechoso es la caída simétrica, que no concuerda con lo esperado según un proceso exponencial.
¿Será un efecto tapadera de los recuperados? Si hay muchos, pueden encubrir a los susceptibles. Veamos la simulación quitándolos:
Figura 11. Sin recuperados. Escasa diferencia, así que no merece la pena, porque después el código se volverá más complicado y mucho menos elegante.
¿Será un efecto de la convalecencia, que no tiene un valor constante? Veamos cómo se distribuye la convalecencia:
Vídeo 2. Distribución de tiempo de convalecencia. Conforme van entrando individuos en el periodo de convalecencia, van saliendo por el otro lado. El tiempo medio de convalecencia cumplida (línea roja) no es constante: al principio es menor y, conforme avanza el tiempo, aumenta. Esto significa que no se puede considerar constante y, por tanto, tampoco \(\gamma\) .
Figura 12. Recuperación de infectados. El modelo diferencial dispersa en el tiempo la aparición de recuperados al considerar homogéneo el grupo de infectados (como se explicó intuitivamente en la Figura 1). En el Vídeo 2 se ve como la salida de convalecencia se produce según una cola tipo FIFO «primero en entrar, primero en salir» . Como consecuencia, la ola de infectados se alarga en el modelo diferencial
Sorprendentemente, al resolver este asunto hemos comprobado que el clásico modelo SIR es realista en la propagación de la epidemia y, sin embargo, falla al explicar el final de la ola porque \(\gamma\) , en realidad, no es constante. Por cierto, ¿qué tipo de función sería? ¡No acaban los flecos!
LS0tCnRpdGxlOiAiQmlydXTDrW4iCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY3NsOiBuYXR1cl9lcy5jc2wKICAgIGNzczogY2hhY2hpMi5jc3MKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgdG9jX2RlcHRoOiAyCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBoaWdobGlnaHQ6IGthdGUKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzInCiAgICBkZl9wcmludDogcGFnZWQKLS0tCgojIEludHJvZHVjY2nDs24KCiAgQXVucXVlIHNlYW4gZXN0cnVjdHVyYXMgc2VuY2lsbGFzLCBsYSB2aWRhIGRlIHVuIHZpcnVzIGVuIGFic29sdXRvIGxvIGVzLiAgTm8gcHVlZGUgc2VyIGRlbWFzaWFkbyBsZXRhbCBuaSBkZW1hc2lhZG8gKmlub2NlbnRlKiwgdGllbmUgcXVlICphcHJlbmRlciogYSB2aXZpciBjb24gc3UgaG9zcGVkYWRvciBzaW4gZXhwcmltaXJsbyBtdWNobyBuaSBwb2NvLCBlbiB1biBqdWVnbyBldm9sdXRpdm8gY29uIG3Dumx0aXBsZXMgZmFjZXRhcyBlIGltcGxpY2FjaW9uZXMuLgoKICBMbyBxdWUgc2lndWUgYSBjb250aW51YWNpw7NuIG5vIGVzIG3DoXMgcXVlIHVuIHNpbXBsZSBlamVyY2ljaW8gZW4gZWwgcXVlIHNlIHBvbmUgYSBwcnVlYmEgZWwgcG9kZXIgZGUgcHJlZGljY2nDs24gZGUgdW5hcyBzaW1wbGVzIGVjdWFjaW9uZXMgeSB1biBqdWVnbyBjb24gc2VuY2lsbGFzIHJlZ2xhcy4gIFN1cyBpbXBsaWNhY2lvbmVzLCBwb3IgdGFudG8sIHNvbiBtw6FzIGhldXLDrXN0aWNhcyBxdWUgYXBsaWNhYmxlcy4gIEN1YWxxdWllciBtb2RlbG8gcXVlIHZlcmRhZGVyYW1lbnRlIHB1ZWRhIHNlciBwcmVkaWN0aXZvIHBhcmEgZWwgY2FzbyBxdWUgdG9kb3MgdGVuZW1vcyBlbiBtZW50ZSBkZWJlIGNvbnNpZGVyYXIgbXVjaG9zIGFzcGVjdG9zIHNlY3VuZGFyaW9zIHF1ZSBhcXXDrSBzZSBvYnZpYW4uCgogIE5vIG9ic3RhbnRlLCBsb3MgcmVzdWx0YWRvcyBzb24gbG8gYmFzdGFudGUgaW50ZXJlc2FudGVzIGNvbW8gcGFyYSBoYWNlcm5vcyBwZW5zYXIgc29icmUgZGV0YWxsZXMgYXBhcmVudGVtZW50ZSB0cml2aWFsZXMgcXVlIGRlc3B1w6lzIHNlIG1hbmlmaWVzdGFuIGRlIGZvcm1hIHNvcnByZW5kZW50ZS4KCgojIE1hdGVtw6F0aWNhIGRlIHVuYSBlcGlkZW1pYQoKICBVbmEgZXBpZGVtaWEgZXMgZWwgZmVuw7NtZW5vIGRlbW9ncsOhZmljbyBwcm92b2NhZG8gcG9yIGxhIGRpc3BlcnNpw7NuIGRlIHVuYSBlbmZlcm1lZGFkIGNvbnRhZ2lvc2EgZW4gdW5hIHBvYmxhY2nDs24uICBMYSBlbmZlcm1lZGFkIHZhIHNhbHRhbmRvIGRlIGluZGl2aWR1byBlbiBpbmRpdmlkdW8gYSB0cmF2w6lzIGRlIHVuIHZlY3RvciwgdW4gdmlydXMgZW4gZXN0ZSBjYXNvLiAgTGEgZXBpZGVtaWEgZXMgbGEgZGluw6FtaWNhIHRlbXBvcmFsIHF1ZSBtYW5pZmllc3RhIGVsIG7Dum1lcm8gZGUgaW5mZWN0YWRvcywgcXVlIHN1ZWxlIGNvbWVuemFyIGRlIHVuYSBtYW5lcmEgKmV4cGxvc2l2YSogKGV4cG9uZW5jaWFsLCBwcm9waWFtZW50ZSBoYWJsYW5kbykgcGFyYSBsbGVnYXIgYSB1biBwaWNvIHkgbHVlZ28gZGlzbWludWlyIGhhc3RhIHF1ZSBkZXNhcGFyZWNlIGxhIGVuZmVybWVkYWQgZGUgbGEgcG9ibGFjacOzbi4KCiMjIEVjdWFjaW9uZXMKCiAgRWwgbW9kZWxvIG3DoXMgc2VuY2lsbG8gc3VyZ2UgYSBwYXJ0aXIgZGUgbG9zIHNpZ3VpZW50ZXMgYXhpb21hczoKICAKICAtIEN1YWxxdWllciBpbmRpdmlkdW8gc3VzY2VwdGlibGUgcHVlZGUgY29udHJhZXIgbGEgZW5mZXJtZWRhZCBjb24gY2llcnRhIHByb2JhYmlsaWRhZCBlbiB1biBwbGF6byBkZXRlcm1pbmFkby4KICAKICAtIEVzdGEgcHJvYmFiaWxpZGFkIGF1bWVudGEgcHJvcG9yY2lvbmFsbWVudGUgYWwgbsO6bWVybyBkZSBpbmZlY3RhZG9zLgogIAogIC0gQWwgY2FibyBkZSBjaWVydG8gdGllbXBvIGxhIGVuZmVybWVkYWQgY2VzYSBlbiBlbCBpbmZlY3RhZG8sIGJpZW4gY29uIHN1IGlubXVuaXphY2nDs24gbyBjb24gc3UgbXVlcnRlLCBjb24gZWwgZWZlY3RvIG5ldG8gZGUgc2FjYXJsbyBkZSBsYSBwb2JsYWNpw7NuIHN1c2NlcHRpYmxlIG8gaW5mZWN0YWRhLgoKICBDb24gZXN0YXMgcHJlbWlzYXMgZGUgcGFydGlkYSwgZWwgcGFyIGRlIHNlc3Vkb3MgbWF0ZW3DoXRpY29zIGluZ2xlc2VzIFtLZXJtYWNrIHkgS2VuZHJpY2tdKGh0dHBzOi8vcm95YWxzb2NpZXR5cHVibGlzaGluZy5vcmcvZG9pLzEwLjEwOTgvcnNwYS4xOTI3LjAxMTgpIGEgcGFydGlyIGRlIHVub3MgW3RyYWJham9zIHByZXZpb3MgbXV5IGVucmV2ZXNhZG9zXShodHRwczovL3d3dy5qc3Rvci5vcmcvc3RhYmxlLzkzNzYwP3JlZnJlcWlkPWV4Y2Vsc2lvciUzQWE5OWRkMDJkNjZhMjNhMzUwYzUxMmJiMjliMzZkOGM2KSBkZWwgdGVuaWVudGUgY29yb25lbCBSb3NzIHkgKHByb2JhYmxlbWVudGUpIHN1IHF1ZXJpZGEgbWFkYW1lIEh1ZHNvbiwgZGVzYXJyb2xsYXJvbiBoYWNlIHVuIHNpZ2xvIHVuIGNvbXBsZXRhIHRlb3LDrWEgbWF0ZW3DoXRpY2EgcXVlLCBzaW1wbGlmaWNhZGEgYWwgY29uc2lkZXJhciB0YXNhcyBjb25zdGFudGVzIHkgdW5hIHBvYmxhY2nDs24gc3VmaWNpZW50ZW1lbnRlIGdyYW5kZSwgc2UgcHVlZGUgcmVzdW1pciBlbiBsYSBzaWd1aWVudGUgZWN1YWNpw7NuOgoKXGJlZ2lue2FsaWdufQogY2FtYmlvXDtlblw7aW5mZWN0YWRvcyA9JiBcO2NvbnRhZ2lvcyAtIHJlY3VwZXJhY2lvbmVzIFxcWzdwdF0KIFxmcmFje2RJfXtkdH0gPSYgXGJldGEgUyBJIC0gXGdhbW1hIEkKXGVuZHthbGlnbn0KCiAgRWwgdMOpcm1pbm8gJFxiZXRhIFMgSSQgcmVwcmVzZW50YSBlbCBuw7ptZXJvIGRlIG51ZXZvcyBjb250YWdpb3MgcG9yIHVuaWRhZCBkZSB0aWVtcG8sIHNpZW5kbyAkUyQgZSAkSSQsIHJlc3BlY3RpdmFtZW50ZSwgZWwgbsO6bWVybyBkZSBzdXNjZXB0aWJsZXMgZSBpbmZlY3RhZG9zIGVuIGxhIHBvYmxhY2nDs247IG1pZW50cmFzIHF1ZSAkXGJldGEkIGVzIHVuIGNvZWZpY2llbnRlIGRlIGNvbnRhZ2lvIHF1ZSBhw7puYSBlbiB1biBzb2xvIHBhcsOhbWV0cm8gbGFzIHByb3BpZWRhZGVzIGNvbnRhZ2lvc2FzIGRlIGxhIGVuZmVybWVkYWQgeSBsb3MgaMOhYml0b3Mgc29jaWFsZXMgZGUgbGEgcG9ibGFjacOzbjogY3VhbnRvIG1heW9yIGVzLCBtw6FzIGbDoWNpbG1lbnRlIHNlIGNvbnRhZ2lhIGxhIGVuZmVybWVkYWQuCgogIFBvciBvdHJvIGxhZG8sICRcZ2FtbWEgSSQgcmVwcmVzZW50YSBsYSAqcmV0aXJhZGEqIGRlIGluZGl2aWR1b3MgaW5mZWN0YWRvcyAoYmllbiBwb3JxdWUgc2UgcmVjdXBlcmFuIHZvbHZpw6luZG9zZSBpbm11bmVzLCBiaWVuIHBvcnF1ZSBwYXNhbiBhIG1lam9yIHZpZGE7IGVsIGNhc28gZXMgcXVlICp5YSBubyBqdWVnYW4qKS4gIEVsIGNvZWZpY2llbnRlICRcZ2FtbWEkIGVzdMOhIHJlbGFjaW9uYWRvIGNvbiBsYSBkdXJhY2nDs24gZGUgbGEgZW5mZXJtZWRhZCwgZW4gcGFydGljdWxhciwgY29uIGVsIHRpZW1wbyBxdWUgZWwgaW5kaXZpZHVvIGVzIGNvbnRhZ2lvc28sIGNvbW8gdmVyZW1vcyBjb24gZGV0YWxsZSBkZW50cm8gZGUgdW4gcmF0by4KCiBTaSBpbmNsdWltb3MgbGEgZGluw6FtaWNhIGRlIGxvcyBzdXNjZXB0aWJsZXMgJFMkIHkgbG9zIHJldGlyYWRvcyAkUiQsIHRlbmRyZW1vcyBlc3RhIHRlcm5hIGRlIGVjdWFjaW9uZXM6CgpcYmVnaW57YWxpZ259CiBcZnJhY3tkU317ZHR9ICY9IC0gXGJldGEgUyBJIFxcWzdwdF0KIFxmcmFje2RJfXtkdH0gJj0gXGJldGEgUyBJIC0gXGdhbW1hIEkgXFxbN3B0XQogXGZyYWN7ZFJ9e2R0fSAmPSBcZ2FtbWEgSQpcZW5ke2FsaWdufQoKCiMjIEVqZW1wbG8gYWNhZMOpbWljbwoKICBQYXJhIGNvbXByZW5kZXIgbWVqb3IgZWwgc2VudGlkbyBkZSBlY3VhY2lvbmVzIHkgcGFyw6FtZXRyb3MsIHZlYW1vcyBjw7NtbyBhcGFyZWNlIGVsIG1vZGVsbyBhIHBhcnRpciBkZSB1bmFzIG9ic2VydmFjaW9uZXMgbmF0dXJhbGVzIHkgbcOhcyBpbnR1aXRpdmFzLiAgSW1hZ2luZW1vcyBxdWUsIGVuIGNpZXJ0YSBwb2JsYWNpw7NuIGNvbiA1MC4wMDAgaGFiaXRhbnRlcyBzdXNjZXB0aWJsZXMgb2N1cnJlIHVuYSBlcGlkZW1pYSB5IHNlIGhhIGNvbXByb2JhZG8gcXVlOgoKICAtIFVuIGluZmVjdGFkbyBjb250YWdpYSBsYSBlbmZlcm1lZGFkIGEgMyBwZXJzb25hcywgZW4gcHJvbWVkaW8uCiAgLSBMYSBlbmZlcm1lZGFkIGVuIGZhc2UgY29udGFnaW9zYSBkdXJhIDEgc2VtYW5hLCBlbiBwcm9tZWRpby4KCiMjIyBDw6FsY3VsbyBkZSAkXGJldGEkCgogIFZhbW9zIGNvbiBsYSBwcmltZXJhIG9ic2VydmFjacOzbi4gwr9Qb2RlbW9zIGRlZHVjaXIgZWwgdmFsb3IgZGUgJFxiZXRhJD8gIEEgdmVyLi4uCgogIDEpIFVuIGluZmVjdGFkbyBjb250YWdpYSBhIDMgc3VzY2VwdGlibGVzOyBjb21vIGxvIHB1ZWRlIGhhY2VyIG1pZW50cmFzIGR1cmEgc3UgZmFzZSBjb250YWdpb3NhICg3IGTDrWFzKSwgY2FkYSBkw61hIGNvbnRhZ2lhcsOhIGEgJFxmcmFjezN9ezd9JCBpbmRpdmlkdW9zLgogIDIpIENvbW8gaGF5ICRJJCBpbmZlY3RhZG9zLCBlbCBuw7ptZXJvIGRlIG51ZXZvcyBjb250YWdpb3MgZGlhcmlvcyBzZXLDoSAkXGZyYWN7M317N31JJC4KICAzKSDCv1kgY8OzbW8gbWV0ZW1vcyAkUyQ/ICBWZWFtb3MuLi4gTGEgcHJpbWVyYSBvYnNlcnZhY2nDs24gZXMgY2xhcmFtZW50ZSBpbmNvbXBsZXRhLCBsZSBmYWx0YSDCqy4uLmFsIHByaW5jaXBpbyBkZSBsYSBlcGlkZW1pYcK7OiBlc3TDoSBjbGFybyBxdWUgbGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSB1biBpbmZlY3RhZG8gKnNlIGxvIHBlZ3VlKiBhIHVuIHN1c2NlcHRpYmxlIGVzIG11Y2hvIG1heW9yIGFsIHByaW5jaXBpbyBkZSBsYSBlcGlkZW1pYSAoY3VhbmRvICRTJCBlcyBncmFuZGUpIHF1ZSBhbCBmaW5hbCAoY3VhbmRvICRTJCBlcyBtZW5vciksIHBvciBwdXJhICpsZXkgZGUgYWNjacOzbiBkZSBtYXNhcyouICBFc3RvIHNpZ25pZmljYSBxdWUgJFxmcmFjezN9ezd9JCBlcyBqdXN0YW1lbnRlICRcYmV0YSBTXzAkLCBzaWVuZG8gJFNfMCQgbGEgcG9ibGFjacOzbiBzdXNjZXB0aWJsZSBpbmljaWFsICg1MC4wMDApLiAgWWEgbG8gdGVuZW1vczoKCiQkXGJldGEgPSBcZnJhY3szfXs3fcK3XGZyYWN7MX17NTAwMDB9ID0gOC41NyBcY2RvdCAxMF57LTZ9IFw7IChcdGV4dHtpbmRpdmlkdW9zfV57LTF9XHRleHR7wrdkw61hfV57LTF9KSQkCgojIyMgQ8OhbGN1bG8gZGUgJFxnYW1tYSQKClZhbW9zIGNvbiBsYSBzZWd1bmRhLiAgwr9Qb2RlbW9zIGRlZHVjaXIgZWwgdmFsb3IgZGUgJFxnYW1tYSQ/ICBQYXJhIHZlcmxvIG3DoXMgZsOhY2lsbWVudGUsIHN1cG9uZ2Ftb3MgcXVlIHRlbmVtb3MgMzUgaW5mZWN0YWRvczsgwr9jdcOhbnRvcyBzZSByZWN1cGVyYXLDoW4gZW4gdW4gZMOtYT8gIExhIGZpZ3VyYSB0YWwgdmV6IGF5dWRlOgoKPGZpZ3VyZT4KICA8aW1nIHNyYz0iZ2FtbWEuc3ZnIj4KICA8ZmlnY2FwdGlvbj4KICAqKkZpZ3VyYSAxLiBTaWduaWZpY2FkbyBkZSAkXGdhbW1hJC4qKiAgQ29tbyBsYSBkdXJhY2nDs24gZGUgbGEgZW5mZXJtZWRhZCBlcyBkZSB1bmEgc2VtYW5hLCBjdWFuZG8gcGFzZSAxIGTDrWEgc2UgcmVjdXBlcmFyw6FuIDUgZGUgbG9zIDM1IGluZmVjdGFkb3MsIGVzIGRlY2lyICR7MX0vezd9JCBxdWUgZXMganVzdG8gZWwgdmFsb3IgZGUgJFxnYW1tYSQuICBBc8OtIHF1ZSAkXGdhbW1hJCBlcywgaW50dWl0aXZhbWVudGUsIGVsIGludmVyc28gZGUgbGEgZHVyYWNpw7NuIGRlIGxhIGVuZmVybWVkYWQuCiAgPC9maWdjYXB0aW9uPgo8L2ZpZ3VyZT4KCiAgRW4gcHJpbmNpcGlvLCBwb3JxdWUgeWEgdmVyZW1vcyBtw6FzIGFkZWxhbnRlLiAgRWwgcmF6b25hbWllbnRvIGFudGVyaW9yIGFzdW1lIHF1ZSB0ZW5lbW9zIGluZmVjdGFkb3MgcmVjaWVudGVzIHkgdmV0ZXJhbm9zIGVuIGxhIG1pc21hIHByb3BvcmNpw7NuIChsb3MgcHVudGl0b3Mgcm9qb3Mgc2UgZGlzdHJpYnV5ZW4gaG9tb2fDqW5lYW1lbnRlIGVuIGVsIHBsYXpvIGRlIGNvbnZhbGVjZW5jaWEpLiAgTm8gZXMgZGlmw61jaWwgZGVtb3N0cmFyIHF1ZSBlc3RhIHByZW1pc2Egc2UgY3VtcGxlIHNpZW1wcmUgZW4gdW4gZXN0YWRvIGVzdGFjaW9uYXJpbyBwZXJvLCBjb21vIGxhIGVwaWRlbWlhIGN1cnNhIGVuIGZvcm1hIGRlIG9uZGEsIGVzdG8gc3Vwb25kcsOhIHVuIHByb2JsZW1hIHF1ZSBzb2x1Y2lvbmFyZW1vcyBtw6FzIGFkZWxhbnRlLgoKIyMjIERpbsOhbWljYQoKICBZYSB0ZW5lbW9zIHRvZG8uICBTaSBpbnRlZ3JhbW9zIGxhcyBlY3VhY2lvbmVzIHZlcmVtb3MgZWwgYXNwZWN0byBncsOhZmljbyBkZSBsYSBlcGlkZW1pYToKCmBgYHtyfQp7CiMgSU5URUdSQUNJw5NOIERFIExBUyBFQ1VBQ0lPTkVTIFMuSS5SLgoKIy0tLS0gdGllbXBvIGZpbmFsCnRpZW1wb19maW5hbCA8LSAxMDAKdCA8LSBzZXEoZnJvbSA9IDEsIHRvID0gdGllbXBvX2ZpbmFsKQoKIy0tLS0gY29uZGljaW9uZXMgaW5pY2lhbGVzIHkgdmFsb3JlcyBkZSBjb2VmaWNpZW50ZXMKUyA8LSBudW1lcmljKCkKU1sxXSA8LSA1MDAwMCAjIHN1c2NlcHRpYmxlcyBpbmljaWFsZXMKSSA8LSBudW1lcmljKCkKSVsxXSA8LSAxICAgICAgIyBpbmZlY3RhZG9zIGluaWNpYWxlcwpSIDwtIG51bWVyaWMoKQpSWzFdIDwtIDAgICAgICAjIHJldGlyYWRvcyBpbmljaWFsZXMKYmV0YSA8LSA4LjU3RS02CmdhbWEgPC0gMS83CgojLS0tLSBidWNsZSBpbnRlZ3JhY2nDs24gRXVsZXIKZm9yIChpIGluIDE6KGxlbmd0aCh0KS0xKSl7CiAgY29udGFnaW9zIDwtIGJldGEqU1tpXSpJW2ldCiAgcmV0aXJhZG9zIDwtIGdhbWEqSVtpXQogIFNbaSsxXSA8LSBTW2ldIC0gY29udGFnaW9zCiAgSVtpKzFdIDwtIElbaV0gKyAoY29udGFnaW9zIC0gcmV0aXJhZG9zKQogIFJbaSsxXSA8LSBSW2ldICsgcmV0aXJhZG9zCn0KCiMtLS0tIGdyw6FmaWNvCnBsb3QodCwgUywgeWxpbSA9IGMoMCwgNTAwMDApLCB0eXBlID0gImwiLCBjb2wgPSAiZ3JlZW4iLCBsd2QgPSAyLAogICAgIHhsYWIgPSAiVElFTVBPIChkw61hcykiLCB5bGFiID0gIklORElWSURVT1MiKQpsaW5lcyh0LCBSLCBjb2wgPSAib3JhbmdlIiwgbHdkID0gMikKbGluZXModCwgSSwgY29sID0gInJlZCIsIGx3ZCA9IDIpCmxlZ2VuZCgwLCA1MDAwMCwgYygiUyIsIkkiLCJSIiksIGx3ZCA9IDIsIGNvbCA9IGMoImdyZWVuIiwgInJlZCIsICJvcmFuZ2UiKSwgY2V4ID0gMC44LCBidHkgPSAibiIpCn0KYGBgCiAgPGZpZ2NhcHRpb24+CiAgKipGaWd1cmEgMi4gRGluw6FtaWNhIGRlIHVuYSBlcGlkZW1pYS4qKiAgTGEgbMOtbmVhIHJvamEgcmVwcmVzZW50YSBsYSBlcGlkZW1pYSwgcHJvcGlhbWVudGUgZGljaGEuICBQdWVkZSBvYnNlcnZhcnNlIGVsIGluaWNpbyBleHBvbmVuY2lhbCwgZWwgcGljbyB5IGxhIHVsdGVyaW9yIGRlY2HDrWRhLCBmYXNlcyB0w61waWNhcyBlbiB0b2RhIGVwaWRlbWlhLiAgT2pvIGEgbGEgbMOtbmVhIHZlcmRlOiBubyB0b2RvcyBsb3Mgc3VzY2VwdGlibGVzIGRlYmVuIHBhc2FyIGxhIGVuZmVybWVkYWQgYW50ZXMgZGUgcXVlIGNlc2UgbGEgZXBpZGVtaWEuCiAgPC9maWdjYXB0aW9uPgoKIyMgQ2FyYWN0ZXLDrXN0aWNhcyBkZSBsYSBkaW7DoW1pY2EgZXBpZMOpbWljYQoKICBFbiBsYSBGaWd1cmEgMiBwb2RlbW9zIGFwcmVjaWFyIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGRpbsOhbWljYXMgZGUgdG9kYSBlcGlkZW1pYTogZWwgaW5pY2lvIGV4cG9uZW5jaWFsLCBlbCBwaWNvIGRlIGluZmVjdGFkb3MgeSBlbCBkZXNjZW5zbyBmaW5hbCBoYXN0YSBsYSBkZXNhcGFyaWNpw7NuIGRlIGxhIGVuZmVybWVkYWQgZW4gbGEgcG9ibGFjacOzbi4gIFVuIGFzcGVjdG8gaW50ZXJlc2FudGUgZXMgcXVlIGxhIGVwaWRlbWlhIHB1ZWRlIChhdW5xdWUgbm8gc2llbXByZSkgYWNhYmFyIGFudGVzIGRlIHF1ZSB0b2RvcyBsb3Mgc3VzY2VwdGlibGVzIHBhc2VuIGxhIGVuZmVybWVkYWQuCgogIE90cmEgY2FyYWN0ZXLDrXN0aWNhIGltcG9ydGFudGUgZXMgbGEgYXNpbWV0csOtYSBkZSBsYSBjdXJ2YTogZWwgaW5pY2lvIGVzIG11Y2hvIG3DoXMgZW1waW5hZG8geSBlbCBkZXNjZW5zbyBtw6FzIGxlbnRvLiAgRXN0byBvY3VycmUgcG9ycXVlIGVsIGNvbnRhZ2lvIGRlcGVuZGUgZGVsIGN1YWRyYWRvIGRlIGxvcyBpbmRpdmlkdW9zIG1pZW50cmFzIHF1ZSBsYSByZWN1cGVyYWNpw7NuIGVzIGZ1bmNpw7NuIGxpbmVhbC4KCiMjIyBFZmVjdG8gZGUgbGEgZGVuc2lkYWQgZGUgcG9ibGFjacOzbgoKICBFbCB0YW1hw7FvIGRlIGxhIHBvYmxhY2nDs24gdGFtYmnDqW4gZXMgdW4gZmFjdG9yIGNyw610aWNvLiAgUG9kZW1vcyB2ZXJsbyBtZWpvciBzaSBleHByZXNhbW9zIGxvcyBpbmZlY3RhZG9zIGVuICUgZGUgbGEgcG9ibGFjacOzbiB5IGhhY2Vtb3MgdmFyaWFzIHNpbXVsYWNpb25lcyBjb24gZGlzdGludGFzIGRlbnNpZGFkZXMgZGUgcG9ibGFjacOzbiwgcG9yIGVqZW1wbG8gY29uIDQwMC4wMDAsIDIwMC4wMDAsIDEwMC4wMDAsIDI1LjAwMCB5IDEyLjAwMCBhbG1hczoKCmBgYHtyIGVjaG89RkFMU0V9CiMgSU5URUdSQUNJw5NOIERFIExBUyBFQ1VBQ0lPTkVTIFMuSS5SLiAoQ09NUEFSQVRJVkEpCgojLS0tLSB0aWVtcG8gZmluYWwgZSBpbnRlcnZhbG8gZGUgaW50ZWdyYWNpw7NuCnRpZW1wb19maW5hbCA8LSAyMDAKZGVsdGFfdCA8LSAwLjEgIyByZWR1Y2UgZWwgZXJyb3IgZGUgaW50ZWdyYWNpw7NuIGNvbiBTIGdyYW5kZXMKdCA8LSBzZXEoZnJvbSA9IDEsIHRvID0gdGllbXBvX2ZpbmFsLCBieSA9IGRlbHRhX3QpCgojIFMwID0gNTAuMDAwCiMtLS0tIGNvbmRpY2lvbmVzIGluaWNpYWxlcyB5IHZhbG9yZXMgZGUgY29lZmljaWVudGVzClMgPC0gbnVtZXJpYygpClNbMV0gPC0gNTAwMDAgIyBzdXNjZXB0aWJsZXMgaW5pY2lhbGVzCkkgPC0gbnVtZXJpYygpCklbMV0gPC0gMSAgICAgICMgaW5mZWN0YWRvcyBpbmljaWFsZXMKUiA8LSBudW1lcmljKCkKUlsxXSA8LSAwICAgICAgIyByZXRpcmFkb3MgaW5pY2lhbGVzCmJldGEgPC0gOC41N0UtNgpnYW1hIDwtIDEvNwojLS0tLSBidWNsZSBpbnRlZ3JhY2nDs24gRXVsZXIKZm9yIChpIGluIDE6KGxlbmd0aCh0KS0xKSl7CiAgY29udGFnaW9zIDwtIGJldGEqU1tpXSpJW2ldCiAgcmV0aXJhZG9zIDwtIGdhbWEqSVtpXQogIFNbaSsxXSA8LSBTW2ldIC0gY29udGFnaW9zKmRlbHRhX3QKICBJW2krMV0gPC0gSVtpXSArIChjb250YWdpb3MgLSByZXRpcmFkb3MpKmRlbHRhX3QKICBSW2krMV0gPC0gUltpXSArIHJldGlyYWRvcypkZWx0YV90Cn0KIy0tLS0gY29udmVydGlyIGEgcG9yY2VudGFqZQpJIDwtIDEwMCpJL1NbMV0KIy0tLS0gZ3LDoWZpY28KcGxvdCh0LCBJLCB5bGltID0gYygwLCAxMDApLCB0eXBlID0gImwiLCBjb2wgPSAicmVkIiwgbHdkID0gMiwKICAgICB4bGFiID0gIlRJRU1QTyAoZMOtYXMpIiwgeWxhYiA9ICIlIFBPQkxBQ0nDk04gSU5GRUNUQURBIikKdGV4dCgxOTUsIDEwMCwgIkhBQklUQU5URVMiLCBjZXggPSAwLjYpCmxlZ2VuZCgxNzAsIDEwMCwgYygiNDAwLjAwMCIsIjIwMC4wMDAiLCIxMDAuMDAwIiwiNTAuMDAwIiwiMjUuMDAwIiwiMTIuMDAwIiksCiAgICAgICBsd2QgPSAyLCBjb2wgPSBjKCJtYWdlbnRhNCIsIm1hZ2VudGEzIiwgIm1hZ2VudGEiLCJyZWQiLCJzaWVubmEzIiwicGluayIpLAogICAgICAgY2V4ID0gMC44LCBidHkgPSAibiIpCgojIFMwID0gNDAwLjAwMAojLS0tLSBjb25kaWNpb25lcyBpbmljaWFsZXMgeSB2YWxvcmVzIGRlIGNvZWZpY2llbnRlcwpTIDwtIG51bWVyaWMoKQpTWzFdIDwtIDQwMDAwMCAjIHN1c2NlcHRpYmxlcyBpbmljaWFsZXMKSSA8LSBudW1lcmljKCkKSVsxXSA8LSAxICAgICAgIyBpbmZlY3RhZG9zIGluaWNpYWxlcwpSIDwtIG51bWVyaWMoKQpSWzFdIDwtIDAgICAgICAjIHJldGlyYWRvcyBpbmljaWFsZXMKYmV0YSA8LSA4LjU3RS02CmdhbWEgPC0gMS83CiMtLS0tIGJ1Y2xlIGludGVncmFjacOzbiBFdWxlcgpmb3IgKGkgaW4gMToobGVuZ3RoKHQpLTEpKXsKICBjb250YWdpb3MgPC0gYmV0YSpTW2ldKklbaV0KICByZXRpcmFkb3MgPC0gZ2FtYSpJW2ldCiAgU1tpKzFdIDwtIFNbaV0gLSBjb250YWdpb3MqZGVsdGFfdAogIElbaSsxXSA8LSBJW2ldICsgKGNvbnRhZ2lvcyAtIHJldGlyYWRvcykqZGVsdGFfdAogIFJbaSsxXSA8LSBSW2ldICsgcmV0aXJhZG9zKmRlbHRhX3QKfQojLS0tLSBjb252ZXJ0aXIgYSBwb3JjZW50YWplCkkgPC0gMTAwKkkvU1sxXQojLS0tLSBncsOhZmljbwpsaW5lcyh0LCBJLCBjb2wgPSAibWFnZW50YTQiLCBsd2QgPSAyKQoKIyBTMCA9IDIwMC4wMDAKIy0tLS0gY29uZGljaW9uZXMgaW5pY2lhbGVzIHkgdmFsb3JlcyBkZSBjb2VmaWNpZW50ZXMKUyA8LSBudW1lcmljKCkKU1sxXSA8LSAyMDAwMDAgIyBzdXNjZXB0aWJsZXMgaW5pY2lhbGVzCkkgPC0gbnVtZXJpYygpCklbMV0gPC0gMSAgICAgICMgaW5mZWN0YWRvcyBpbmljaWFsZXMKUiA8LSBudW1lcmljKCkKUlsxXSA8LSAwICAgICAgIyByZXRpcmFkb3MgaW5pY2lhbGVzCmJldGEgPC0gOC41N0UtNgpnYW1hIDwtIDEvNwojLS0tLSBidWNsZSBpbnRlZ3JhY2nDs24gRXVsZXIKZm9yIChpIGluIDE6KGxlbmd0aCh0KS0xKSl7CiAgY29udGFnaW9zIDwtIGJldGEqU1tpXSpJW2ldCiAgcmV0aXJhZG9zIDwtIGdhbWEqSVtpXQogIFNbaSsxXSA8LSBTW2ldIC0gY29udGFnaW9zKmRlbHRhX3QKICBJW2krMV0gPC0gSVtpXSArIChjb250YWdpb3MgLSByZXRpcmFkb3MpKmRlbHRhX3QKICBSW2krMV0gPC0gUltpXSArIHJldGlyYWRvcypkZWx0YV90Cn0KIy0tLS0gY29udmVydGlyIGEgcG9yY2VudGFqZQpJIDwtIDEwMCpJL1NbMV0KIy0tLS0gZ3LDoWZpY28KbGluZXModCwgSSwgY29sID0gIm1hZ2VudGEzIiwgbHdkID0gMikKCiMgUzAgPSAxMDAuMDAwCiMtLS0tIGNvbmRpY2lvbmVzIGluaWNpYWxlcyB5IHZhbG9yZXMgZGUgY29lZmljaWVudGVzClMgPC0gbnVtZXJpYygpClNbMV0gPC0gMTAwMDAwICMgc3VzY2VwdGlibGVzIGluaWNpYWxlcwpJIDwtIG51bWVyaWMoKQpJWzFdIDwtIDEgICAgICAjIGluZmVjdGFkb3MgaW5pY2lhbGVzClIgPC0gbnVtZXJpYygpClJbMV0gPC0gMCAgICAgICMgcmV0aXJhZG9zIGluaWNpYWxlcwpiZXRhIDwtIDguNTdFLTYKZ2FtYSA8LSAxLzcKIy0tLS0gYnVjbGUgaW50ZWdyYWNpw7NuIEV1bGVyCmZvciAoaSBpbiAxOihsZW5ndGgodCktMSkpewogIGNvbnRhZ2lvcyA8LSBiZXRhKlNbaV0qSVtpXQogIHJldGlyYWRvcyA8LSBnYW1hKklbaV0KICBTW2krMV0gPC0gU1tpXSAtIGNvbnRhZ2lvcypkZWx0YV90CiAgSVtpKzFdIDwtIElbaV0gKyAoY29udGFnaW9zIC0gcmV0aXJhZG9zKSpkZWx0YV90CiAgUltpKzFdIDwtIFJbaV0gKyByZXRpcmFkb3MqZGVsdGFfdAp9CiMtLS0tIGNvbnZlcnRpciBhIHBvcmNlbnRhamUKSSA8LSAxMDAqSS9TWzFdCiMtLS0tIGdyw6FmaWNvCmxpbmVzKHQsIEksIGNvbCA9ICJtYWdlbnRhIiwgbHdkID0gMikKCiMgUzAgPSAyNS4wMDAKIy0tLS0gY29uZGljaW9uZXMgaW5pY2lhbGVzIHkgdmFsb3JlcyBkZSBjb2VmaWNpZW50ZXMKUyA8LSBudW1lcmljKCkKU1sxXSA8LSAyNTAwMCAjIHN1c2NlcHRpYmxlcyBpbmljaWFsZXMKSSA8LSBudW1lcmljKCkKSVsxXSA8LSAxICAgICAgIyBpbmZlY3RhZG9zIGluaWNpYWxlcwpSIDwtIG51bWVyaWMoKQpSWzFdIDwtIDAgICAgICAjIHJldGlyYWRvcyBpbmljaWFsZXMKYmV0YSA8LSA4LjU3RS02CmdhbWEgPC0gMS83CiMtLS0tIGJ1Y2xlIGludGVncmFjacOzbiBFdWxlcgpmb3IgKGkgaW4gMToobGVuZ3RoKHQpLTEpKXsKICBjb250YWdpb3MgPC0gYmV0YSpTW2ldKklbaV0KICByZXRpcmFkb3MgPC0gZ2FtYSpJW2ldCiAgU1tpKzFdIDwtIFNbaV0gLSBjb250YWdpb3MqZGVsdGFfdAogIElbaSsxXSA8LSBJW2ldICsgKGNvbnRhZ2lvcyAtIHJldGlyYWRvcykqZGVsdGFfdAogIFJbaSsxXSA8LSBSW2ldICsgcmV0aXJhZG9zKmRlbHRhX3QKfQojLS0tLSBjb252ZXJ0aXIgYSBwb3JjZW50YWplCkkgPC0gMTAwKkkvU1sxXQojLS0tLSBncsOhZmljbwpsaW5lcyh0LCBJLCBjb2wgPSAic2llbm5hMyIsIGx3ZCA9IDIpCgojIFMwID0gMTIuMDAwCiMtLS0tIGNvbmRpY2lvbmVzIGluaWNpYWxlcyB5IHZhbG9yZXMgZGUgY29lZmljaWVudGVzClMgPC0gbnVtZXJpYygpClNbMV0gPC0gMTIwMDAgIyBzdXNjZXB0aWJsZXMgaW5pY2lhbGVzCkkgPC0gbnVtZXJpYygpCklbMV0gPC0gMSAgICAgICMgaW5mZWN0YWRvcyBpbmljaWFsZXMKUiA8LSBudW1lcmljKCkKUlsxXSA8LSAwICAgICAgIyByZXRpcmFkb3MgaW5pY2lhbGVzCmJldGEgPC0gOC41N0UtNgpnYW1hIDwtIDEvNwojLS0tLSBidWNsZSBpbnRlZ3JhY2nDs24gRXVsZXIKZm9yIChpIGluIDE6KGxlbmd0aCh0KS0xKSl7CiAgY29udGFnaW9zIDwtIGJldGEqU1tpXSpJW2ldCiAgcmV0aXJhZG9zIDwtIGdhbWEqSVtpXQogIFNbaSsxXSA8LSBTW2ldIC0gY29udGFnaW9zKmRlbHRhX3QKICBJW2krMV0gPC0gSVtpXSArIChjb250YWdpb3MgLSByZXRpcmFkb3MpKmRlbHRhX3QKICBSW2krMV0gPC0gUltpXSArIHJldGlyYWRvcypkZWx0YV90Cn0KIy0tLS0gY29udmVydGlyIGEgcG9yY2VudGFqZQpJIDwtIDEwMCpJL1NbMV0KIy0tLS0gZ3LDoWZpY28KbGluZXModCwgSSwgY29sID0gInBpbmsiLCBsd2QgPSAyKQoKYGBgCgogIDxmaWdjYXB0aW9uPgogICoqRmlndXJhIDMuIEVmZWN0byBkZSBsYSBkZW5zaWRhZCBkZSBwb2JsYWNpw7NuLioqICBMYSBtaXNtYSBlbmZlcm1lZGFkIGRlc2VuY2FkZW5hIGRpc3RpbnRvcyB0aXBvcyBkZSBlcGlkZW1pYSBkZXBlbmRpZW5kbyBkZWwgdGFtYcOxbyBkZSBsYSBwb2JsYWNpw7NuIHN1c2NlcHRpYmxlOiBjdWFudG8gbWF5b3IgZXMgbGEgcG9ibGFjacOzbiwgbcOhcyByw6FwaWRhbWVudGUgc2UgZGVzZW5jYWRlbmEgbGEgZXBpZGVtaWEsIG1heW9yIHBvcmNlbnRhamUgZGUgbGEgcG9ibGFjacOzbiBzZSBhZmVjdGEgeSBhbnRlcyBhY2FiYSBlbCBwcm9jZXNvLiAgUGVyby4uLiDCv3F1w6kgb2N1cnJlIGNvbiBsYSBkZSAxMi4wMDAgaGFiaXRhbnRlcz8KICA8L2ZpZ2NhcHRpb24+CgogIEVmZWN0aXZhbWVudGUsIGN1YW50byBtYXlvciBlcyBsYSBwb2JsYWNpw7NuLCBtw6FzIGRldmFzdGFkb3JhIGVzIGxhIGVwaWRlbWlhLiAgTG9zIGVmZWN0b3MgZW4gcG9ibGFjaW9uZXMgbWVub3JlcyBzb24gY2FkYSB2ZXogbcOhcyBzdWF2ZXMsIGxsZWdhbmRvIGFsIGV4dHJlbW8sIGVuIGxhIGNpdWRhZCBjb24gMTIuMDAwIGhhYml0YW50ZXMsIGRlIG5pIHNpcXVpZXJhIHByb2R1Y2lyc2UgbGEgZXBpZGVtaWEsIGEgcGVzYXIgZGUgdHJhdGFyc2UgZGUgbGEgbWlzbWEgZW5mZXJtZWRhZCB5IGVsIG1pc21vIHRpcG8gY29zdHVtYnJlcyBzb2NpYWxlcy4gIMK/UG9yIHF1w6k/CgogIExhIG1heW9yIHZpcnVsZW5jaWEgZW4gcG9ibGFjaW9uZXMgZ3JhbmRlcyBwb2RlbW9zIGNvbXByZW5kZXJsYSBpbnR1aXRpdmFtZW50ZTogc2kgdW4gaW5mZWN0YWRvIGNvbnRhZ2lhYmEgYSAzIHBlcnNvbmFzIGVuIHVuYSBjaXVkYWQgZGUgNTAuMDAwIGluZGl2aWR1b3MsIGVudG9uY2VzLCBlbiB1bmEgY2l1ZGFkIGRlIDQwMC4wMDAgaGFiaXRhbnRlcyAoOCB2ZWNlcyBtw6FzIHBvYmxhZGEpIGNvbnRhZ2lhcsOhIGEgMjQgKDggdmVjZXMgbcOhcykgeSwgcG9yIHRhbnRvLCBsYSB2ZWxvY2lkYWQgZGUgcHJvcGFnYWNpw7NuIHNlcsOhIDggdmVjZXMgbWF5b3IgcXVlIGVuIGxhIGNpdWRhZCBkZSA1MC4wMDAgYWxtYXMuCgojIyBFbCBmYWN0b3IgJFJfMCQKCiAgQWwgZmFjdG9yIHBvciBlbCBxdWUgc2UgbXVsdGlwbGljYSBsYSBpbmZlY2Npw7NuIChvIG7Dum1lcm8gZGUgaW5kaXZpZHVvcyBhIGxvcyBxdWUgY29udGFnaWEgdW4gaW5mZWN0YWRvKSBzZSBkZW5vbWluYSAkUl8wJCB5IHZlbW9zIHF1ZSBlcyBkaXJlY3RhbWVudGUgcHJvcG9yY2lvbmFsIGEgbGEgZGVuc2lkYWQgZGUgcG9ibGFjacOzbi4gIFBvZGVtb3MgY2FsY3VsYXIgc3UgdmFsb3Igc2luIG5lY2VzaWRhZCBkZSBhY3VkaXIgYSBsYXMgZGlmZXJlbmNpYWxlczogYWwgaW52ZXJ0aXIgZWwgcmF6b25hbWllbnRvIG1lZGlhbnRlIGVsIHF1ZSBjYWxjdWxhbW9zICRcYmV0YSQgeSAkXGdhbW1hJCB2ZW1vcyBxdWUKICAKJCRSXzAgPSBcZnJhY3tcYmV0YSBTfXtcZ2FtbWF9JCQKCllhIHRlbmVtb3Mgc3UgdmFsb3IgcGFyYSBsYSBjaXVkYWQgZGUgNTAuMDAwIHBlcnNvbmFzIChlcmEgdW5vIGRlIGxvcyBheGlvbWFzKSB5IGhlbW9zIGhlY2hvIGVsIGPDoWxjdWxvIHBhcmEgbGEgcG9ibGFjacOzbiBkZSA0MDAuMDAwIGhhYml0YW50ZXMuICBQb3IgY3VyaW9zaWRhZCwgYXBsaXF1w6ltb3NsbyBhIGxhcyBvdHJhcyBwb2JsYWNpb25lczoKCnxIQUJJVEFOVEVTIHwgJFJfMCQgKGFsIGluaWNpbyBkZSBsYSBlcGlkZW1pYSkgfAp8LS0tLS0tLS06fC0tLS0tOnwKfCA0MDAuMDAwIHwgMjQgICB8CnwgMjAwLjAwMCB8IDEyICAgfAp8IDEwMC4wMDAgfCA2ICAgIHwKfCAgNTAuMDAwIHwgMyAgICB8CnwgIDI1LjAwMCB8IDEuNSAgfAp8ICAxMi4wMDAgfCAwLjc1IHwKCsKhQWggbWlnbyEgIEVuIGxhIMO6bHRpbWEgbMOtbmVhIHRlbmVtb3MgbGEgZXhwbGljYWNpw7NuIGRlbCBmcmFjYXNvIGRlIGxhIGVwaWRlbWlhIGVuIGxhIGNpdWRhZCBwZXF1ZcOxYTogc2kgdW4gaW5mZWN0YWRvIHNvbG8gZXMgY2FwYXogZGUgdHJhbnNtaXRpciBsYSBlbmZlcm1lZGFkIGEgMy80IGRlIHBlcnNvbmEsIGVzdMOhIGNsYXJvIHF1ZSBsYSBlcGlkZW1pYSBubyBzZSBwcm9kdWNpcsOhLiAgUGFyYSBxdWUgZXhwbG90ZSBsYSBlcGlkZW1pYSwgJFJfMCQgZGViZSBzZXIgbWF5b3IgcXVlIDEuCgogIENvbW8gZGVwZW5kZSBkaXJlY3RhbWVudGUgZGUgJFMkIHkgw6lzdG9zIHZhbiBzaWVtcHJlIGRpc21pbnV5ZW5kbywgZWwgZmFjdG9yICRSXzAkIHRhbWJpw6luIHZhIGRpc21pbnV5ZW5kbyBkZXNkZSBlbCBpbmljaW8gZGUgbGEgZXBpZGVtaWEuICBWZcOhbW9zbG8gZW4gZWwgcHJpbWVyIGdyw6FmaWNvOgpgYGB7ciBlY2hvPUZBTFNFfQojIElOVEVHUkFDScOTTiBERSBMQVMgRUNVQUNJT05FUyBTLkkuUi4gWSBDw4FMQ1VMTyBERSBSbwoKIy0tLS0gdGllbXBvIGZpbmFsCnRpZW1wb19maW5hbCA8LSAxMDAKdCA8LSBzZXEoZnJvbSA9IDEsIHRvID0gdGllbXBvX2ZpbmFsKQoKIy0tLS0gY29uZGljaW9uZXMgaW5pY2lhbGVzIHkgdmFsb3JlcyBkZSBjb2VmaWNpZW50ZXMKUyA8LSBudW1lcmljKCkKU1sxXSA8LSA1MDAwMCAjIHN1c2NlcHRpYmxlcyBpbmljaWFsZXMKSSA8LSBudW1lcmljKCkKSVsxXSA8LSAxICAgICAgIyBpbmZlY3RhZG9zIGluaWNpYWxlcwpSIDwtIG51bWVyaWMoKQpSWzFdIDwtIDAgICAgICAjIHJldGlyYWRvcyBpbmljaWFsZXMKYmV0YSA8LSA4LjU3RS02CmdhbWEgPC0gMS83CgojLS0tLSBidWNsZSBpbnRlZ3JhY2nDs24gRXVsZXIKZm9yIChpIGluIDE6KGxlbmd0aCh0KS0xKSl7CiAgY29udGFnaW9zIDwtIGJldGEqU1tpXSpJW2ldCiAgcmV0aXJhZG9zIDwtIGdhbWEqSVtpXQogIFNbaSsxXSA8LSBTW2ldIC0gY29udGFnaW9zCiAgSVtpKzFdIDwtIElbaV0gKyAoY29udGFnaW9zIC0gcmV0aXJhZG9zKQogIFJbaSsxXSA8LSBSW2ldICsgcmV0aXJhZG9zCn0KCiMtLS0tIGPDoWxjdWxvIGRlIFJvClIwIDwtIGJldGEqUy9nYW1hCgojLS0tLSBncsOhZmljbyAoY29uIGRvcyBlamVzIFkgZXMgbXV5IGVuZ29ycm9zbywgcGVyby4uLikKcGFyKG1hciA9IGMoNSw0LDQsNCkgKyAwLjEpCnBsb3QodCwgSSwgeWxpbSA9IGMoMCwgMjAwMDApLCB0eXBlID0gImwiLCBjb2wgPSAicmVkIiwgbHdkID0gMiwKICAgICB4bGFiID0gIlRJRU1QTyAoZMOtYXMpIiwgeWxhYiA9ICJJTkZFQ1RBRE9TIikKbGVnZW5kKDkwLCAyMDAwMCwgYygiSSIsIlJvIiksIGx3ZCA9IDIsIGNvbCA9IGMoInJlZCIsICJjb3JuZmxvd2VyYmx1ZSIpLAogICAgICAgY2V4ID0gMC44LCBidHkgPSAibiIpCnBhcihuZXcgPSBUUlVFKQpwbG90KHQsIFIwLCB5bGltID0gYygwLCAzKSwgdHlwZSA9ICJsIiwgY29sID0gImNvcm5mbG93ZXJibHVlIiwgbHdkID0gMiwKICAgICBtYWluID0iIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikKYWJsaW5lKGggPSAxLCBsdHkgPSAyKQpheGlzKHNpZGUgPSA0KQptdGV4dCgiUjAiLCBzaWRlID0gNCwgbGluZSA9IDMpCmBgYAogIDxmaWdjYXB0aW9uPgogICoqRmlndXJhIDQuIEV2b2x1Y2nDs24gZGUgJFJfMCQuKiogIEVsIG1pc21vIGdyw6FmaWNvIGRlIGFudGVzICg1MC4wMDAgc3VzY2VwdGlibGVzKSwgcGVybyBhaG9yYSBjb24gZWwgdmFsb3IgZGUgJFJfMCQgc3VwZXJwdWVzdG8uICBTdSBjdXJ2YSBlcyBpZMOpbnRpY2EgYSBsYSBkZSBTLCBkZSBoZWNobywgZXMgbGEgbWlzbWEgbXVsdGlwbGljYWRhIHBvciAke1xiZXRhfS97XGdhbW1hfSQuICBPYnNlcnZhIHF1ZSwganVzdG8gY3VhbmRvICRSXzAkIGNydXphIGVsIHVtYnJhbCBkZSAxLCBsYSBlcGlkZW1pYSBhbGNhbnphIHN1IHBpY28geSBjb21pZW56YSBhIGRlY2xpbmFyLgogIDwvZmlnY2FwdGlvbj4KCgojIEVqZW1wbG8gcmVhbAoKRWwgaW5pY2lvIGRlIGxhIGVwaWRlbWlhIGRlICpDT1ZJRCogZW4gbGEgQ29zdGEgZGVsIFNvbCBub3MgZGEgdW4gZWplbXBsbywgdGFuIGlsdXN0cmF0aXZvIGNvbW8gdHJpc3RlLCBkZSBlc3RhcyBzaW1wbGUgbWF0ZW3DoXRpY2FzLiAgTGFzIHByaW1lcmFzIHNlbWFuYXMgZGUgcHJvcGFnYWNpw7NuIGRlIGxhIGVuZmVybWVkYWQgb2N1cnJpZXJvbiBjb24gZXN0YSBjaWZyYXMgb2ZpY2lhbGVzOgoKRkVDSEEgfCBJTkZFQ1RBRE9TCjotLS0tLS06fC0tLS0tLS0tLS0tOgoyNy8yLzIwCXwgMQoyOC8yLzIwCXwgNAoyOS8yLzIwCXwgNgoxLzMvMjAJfCA2CjIvMy8yMAl8IDYKMy8zLzIwCXwgNwo0LzMvMjAJfCA3CjUvMy8yMAl8IDkKNi8zLzIwCXwgMTgKNy8zLzIwCXwgMjIKOC8zLzIwICB8IDI3CjkvMy8yMCAgfCA0MgoxMC8zLzIwIHwgNTkKMTEvMy8yMCB8IDc3CjEyLzMvMjAgfCA5NwoxMy8zLzIwIHwgMTI4CjE0LzMvMjAgfCAxODAKCmBgYHtyIGVjaG89RkFMU0V9CklfcmVhbCA8LSBjKDEsNCw2LDYsNiw3LDcsOSwxOCwyMiwyNyw0Miw1OSw3Nyw5NywxMjgsMTgwKQp0X3JlYWwgPC0gc2VxKDE6bGVuZ3RoKElfcmVhbCkpCnBsb3QodF9yZWFsLCBJX3JlYWwsIHhsYWIgPSAiVElFTVBPIChkw61hcykiLCB5bGFiID0gIklORkVDVEFET1MiKQpgYGAKICA8ZmlnY2FwdGlvbj4KICAqKkZpZ3VyYSA1LiBQcmltZXJhcyBzZW1hbmFzIGRlIGxhICpDT1ZJRCogZW4gbGEgQ29zdGEgZGVsIFNvbC4qKiAgRWwgYXVtZW50byBkZSBpbmZlY3RhZG9zIHNlIHByb2R1am8gZGUgZm9ybWEgZXhwb25lbmNpYWwuCiAgPC9maWdjYXB0aW9uPgoKIyMgQ8OhbGN1bG8gZGUgbG9zIHBhcsOhbWV0cm9zIGVuIE3DoWxhZ2EKCiAgVmVhbW9zIHNpIHBvZGVtb3MgY2FsY3VsYXIgbG9zIHBhcsOhbWV0cm9zIGRlIGxhIGVwaWRlbWlhLiAgRWwgcHJvYmxlbWEgZXMgbXV5IGludGVyZXNhbnRlLCBtYXRlbcOhdGljYW1lbnRlIGhhYmxhbmRvLCBwdWVzIGNvbnNpc3RlIGVuIGVsIGFqdXN0ZSBkZSB1bmEgZnVuY2nDs24gcXVlIG5vIHRpZW5lIHVuYSBleHByZXNpw7NuIGFuYWzDrXRpY2EgZXhwbMOtY2l0YSwgcHVlcyByZXN1bHRhIGRlIGxhIGludGVncmFjacOzbiBudW3DqXJpY2EgZGUgZG9zIGVjdWFjaW9uZXMgZGlmZXJlbmNpYWxlcy4gIERlam8gdW4gZnJlbnRlIGFiaWVydG8sIGludGVudGFuZG8gYWp1c3RhciB0YW50byAkXGJldGEkIHkgJFxnYW1tYSQgY29tbyAkU18wJCBkZSBmb3JtYSBpbmRlcGVuZGllbnRlLCBwb3JxdWUgYWhvcmEgZWwgb2JqZXRpdm8gcHJpbmNpcGFsIGVzIG3DoXMgZXZvbHV0aXZvIHF1ZSBtYXRlbcOhdGljby4gIE5vIG9ic3RhbnRlLCBjb24gdW4gcG9jbyBkZSBoYWJpbGlkYWQgc2UgcHVlZGUgc2ltcGxpZmljYXIgZWwgYXN1bnRvLCBzaSBwb2RlbW9zIGVzdGltYXIgZWwgdmFsb3IgZGUgJFNfMCQgeSAkXGdhbW1hJCBpbmRlcGVuZGllbnRlbWVudGUgZGUgbG9zIGRhdG9zLgoKIyMjIFZhbG9yIGRlICRTXzAkCgogIFByb3BpYW1lbnRlIGRpY2hvLCBubyBlcyB1biBjb2VmaWNpZW50ZSwgcGVybyBzw60gdW4gcGFyw6FtZXRybyBkZWwgbW9kZWxvIHF1ZSBkZWJlbW9zIGFqdXN0YXIuICBEYWRvIHF1ZSBlbCBmb2NvIHByaW5jaXBhbCBzZSBsb2NhbGl6w7MgZW4gdG9kYSBsYSBDb3N0YSBkZWwgU29sICgxLjQwMC4wMDAgaGFiaXRhbnRlcykgeSBlc3RhIHpvbmEgbXVlc3RyYSBwcm9waWVkYWRlcyBkZSBtb3ZpbGlkYWQgeSBjb3N0dW1icmVzIG11eSBob21vZ8OpbmVhcywgcGFyZWNlIGFjZXJ0YWRvIGVtcGV6YXIgY29uIGVzdGUgdmFsb3IuCgojIyMgVmFsb3IgZGUgJFxnYW1tYSQKCiAgTGEgZHVyYWNpw7NuIHRvdGFsIGRlIGxhIGVuZmVybWVkYWQgZXMgbXV5IGluZGVmaW5pZGEsIHZhIGRlc2RlIGxvcyAyNCBhIGxvcyA1NyBkw61hcywgc2Vnw7puIGxhcyBmdWVudGVzIGRlIGRvbmRlIHByb2NlZGEgbGEgaW5mb3JtYWNpw7NuLiAgTm8gb2JzdGFudGUsIGRhZG8gcXVlIGVuIE3DoWxhZ2EgeWEgc2UgYWlzbGFiYW4gYSBsYXMgcGVyc29uYXMgY29uIGxvcyBwcmltZXJvcyBzw61udG9tYXMsIHBhcmEgbnVlc3RybyBjw6FsY3VsbyBzb2xvIHRlbmRyZW1vcyBlbiBjdWVudGEgZWwgdGllbXBvIHF1ZSBlbCByZWNpw6luIGNvbnRhZ2lhZG8gY2lyY3Vsw7MgbGlicmVtZW50ZSBzaW4gbW9zdHJhciBzw61udG9tYXMgcGVybyBzaWVuZG8gY2FwYXogZGUgY29udGFnaWFyIGEgb3Ryb3MsIHVuIHBlcmlvZG8gcXVlIHB1ZWRlIHNlciBkZSB1bmFzIGRvcyBzZW1hbmFzLiAgVG9tYXJlbW9zIHVuIHZhbG9yIGRlIDE1IGTDrWFzIHkgbHVlZ28gY2FsY3VsYXJlbW9zIGxhIGluY2VydGlkdW1icmUgZGVsIHJlc3VsdGFkbyBjb24gcmVzcGVjdG8gYSBlc3RlIGRhdG8sIHNpIGVzIG1lbmVzdGVyLiAgQXPDrSwgdG9tYXJlbW9zIHVuIHZhbG9yIGRlICRcbGFtYmRhID0gMC4wNyBcdGV4dHsgZMOtYXN9XnstMX0kLgoKIyMjIFZhbG9yIGRlICRcYmV0YSQKCiAgTGEgZWN1YWNpw7NuIGNlbnRyYWwgZGVsIG1vZGVsbyBzZSBwdWVkZSBlc2NyaWJpciBkZSBlc3RhIGZvcm1hOgogIAokJFxmcmFje2RJfXtkdH0gPSAoXGJldGEgUyAtIFxnYW1tYSkgSSQkCgpjb21vIGHDum4gYXBhcmVjZSAkUyQgZW4gbGEgZXhwcmVzacOzbiwgc3UgYWp1c3RlIHNpZ3VlIHJlcXVpcmllbmRvIGVsIG3DqXRvZG8gbcOhcyBzb2Zpc3RpY2FkbyBxdWUgdGFsIHZleiBhYm9yZGVtb3MgZW4gb3RyYSBvY2FzacOzbi4gIE5vIG9ic3RhbnRlLCBlbiBhcXVlbCB0aWVtcG8gZWwgbsO6bWVybyBkZSBpbmZlY3RhZG9zIGVyYSBtdXkgcGVxdWXDsW8gKGVuIGNvbXBhcmFjacOzbiBjb24gJFNfMCQpIHkgcG9kZW1vcyBhc3VtaXIgcXVlICRTJCBlcyBwcsOhY3RpY2FtZW50ZSBjb25zdGFudGUgZW4gZXN0b3MgcHJpbWVyb3MgY29tcGFzZXMsIGRlIG1hbmVyYSBxdWU6CgokJFxmcmFje2RJfXtkdH0gXGFwcHJveCAoXGJldGEgU18wIC0gXGdhbW1hKSBJJCQKCmV4cHJlc2nDs24gcXVlIHRpZW5lIGludGVncmFsIGlubWVkaWF0YSB5IGRhIGxhIHNpZ3VpZW50ZSBlY3VhY2nDs246CgokJEkgPSBJXzAgZV57KFxiZXRhIFNfMCAtIFxnYW1tYSkgdH0kJAoKY3V5byBhanVzdGUgZXMgaW5tZWRpYXRvIHBvciBsaW5lYWxpemFjacOzbi4gIFNpbiBlbWJhcmdvLCBwYXJhIGV2aXRhciBlbCBzZXNnbyBxdWUgZXN0byBwcm92b2NhIHNvYnJlIGxvcyBuw7ptZXJvcyBtw6FzIGdyYW5kZXMsIHZhbW9zIGEgYWp1c3RhciBsYSBleHByZXNpw7NuIGRpcmVjdGFtZW50ZSBwb3Igb3B0aW1pemFjacOzbjoKCmBgYHtyfQp7CiMtLS0tIGRhdG9zIHJlYWxlcwpJX3JlYWwgPC0gYygxLDQsNiw2LDYsNyw3LDksMTgsMjIsMjcsNDIsNTksNzcsOTcsMTI4LDE4MCkKbiA8LSBsZW5ndGgoSV9yZWFsKQp0X3JlYWwgPC0gc2VxKDE6bikKcGxvdCh0X3JlYWwsIElfcmVhbCwgeGxhYiA9ICJUSUVNUE8gKGTDrWFzKSIsIHlsYWIgPSAiSU5GRUNUQURPUyIpCgojLS0tLSBwYXLDoW1ldHJvcyBlc3RpbWFkb3MKUzAgPC0gMTQwMDAwMApnYW1hIDwtIDAuMDcKCiMtLS0tIGRlZmluaXIgbGEgc3VtYSBkZSBkaWZlcmVuY2lhcyBjdWFkcmF0aWNhcyBjb21vIGZ1bmNpw7NuClNEQyA8LSBmdW5jdGlvbihkYXQsIHBhcikgewogIEkgPC0gcGFyWzFdKmV4cCgocGFyWzJdKlMwIC0gZ2FtYSkqdF9yZWFsKQogIHdpdGgoZGF0LCBzdW0oKElfcmVhbCAtIEkpXjIpKQp9CgojLS0tLSBidXNjYXIgbG9zIHBhcsOhbWV0cm9zIHF1ZSBsYSBtaW5pbWl6YW4KZGF0b3MgPC0gZGF0YS5mcmFtZSh0X3JlYWwsSV9yZWFsKQpyZXN1bHRhZG8gPC0gb3B0aW0ocGFyID0gYygxLCAxRS03KSwgU0RDLCBkYXQgPSBkYXRvcykKSTAgPC0gcmVzdWx0YWRvJHBhclsxXQpiZXRhIDwtIHJlc3VsdGFkbyRwYXJbMl0KCiMtLS0tIGdyw6FmaWNvIGRlIGxhIG51ZXZhIGN1cnZhIGFqdXN0YWRhCnQgPC0gc2VxKDAsIDIwLCAwLjEpCkkgPC0gSTAqZXhwKChiZXRhKlMwIC0gZ2FtYSkqdCkKbGluZXModCxJLCB0eXBlID0gImwiLCBjb2wgPSAicmVkIiwgbHdkID0gMikKCiMtLS0tIGPDoWxjdWxvIGRlbCBjb2VmaWNpZW50ZSBkZSBkZXRlcm1pbmFjacOzbiBkZSBsYSBudWV2YSBjdXJ2YQpJX2FqIDwtIEkwKmV4cCgoYmV0YSpTMCAtIGdhbWEpKnRfcmVhbCkKUjJjdXJ2YSA8LSAxIC0gc3VtKChJX3JlYWwgLSBJX2FqKV4yKS8oKG4tMSkqdmFyKElfcmVhbCkpCnRleHQoMTIsMTUwLGJxdW90ZShSXjI6LihSMmN1cnZhKSkpCgojLS0tLSBpbmZvcm1hY2nDs24gc29icmUgYmV0YSBlIEkwCnRleHQoNSwxNTAsYnF1b3RlKGJldGE6LihiZXRhKSkpCnRleHQoNSwxMzAsYnF1b3RlKElfMDouKEkwKSkpCn0KYGBgCiAgPGZpZ2NhcHRpb24+CiAgKipGaWd1cmEgNi4gQWp1c3RlIGRlICRcYmV0YSQuKiogIEEgcGVzYXIgZGUgaGFiZXIgZXN0aW1hZG8gZG9zIHBhcsOhbWV0cm9zIHkgYWp1c3RhZG8gZWwgdGVyY2VybywgZXN0ZSBzaW1wbGUgbW9kZWxvIGVzIGNhcGF6IGRlIGV4cGxpY2FyIG3DoXMgZGVsIDk5JSBkZSBsYSB2YXJpYW56YSBkZSBsb3MgZGF0b3MgKCRSXjIgPSAwLjk5NyQpIHkgbm9zIGRhIHVuIHZhbG9yIGRlICRcYmV0YSA9Mi42NMK3MTBeey03fSQgaW5kaXZpZHVvc+KBu8K5IGTDrWHigbvCuS4KICA8L2ZpZ2NhcHRpb24+CgoKICBFbiBlc3RlIG1vZGVsbyBhanVzdGFkbywgdGVuZW1vcyB1biB2YWxvciBkZSAKIAokJFJfMCA9IFxmcmFje1xiZXRhIFNfMH17XGdhbW1hfSA9IFxmcmFjezIuNjTCtzEwXnstN30gwrcgMTQwMDAwMH17MC4wN30gPSA1LjI4JCQKCnF1ZSBjb2luY2lkZSBjb24gbG9zIGPDoWxjdWxvcyBoZWNob3MgcG9yIFttb2RlbG9zIG3DoXMgc29maXN0aWNhZG9zXShodHRwczovL2NtbWlkLmdpdGh1Yi5pby90b3BpY3MvY292aWQxOS9jdXJyZW50LXBhdHRlcm5zLXRyYW5zbWlzc2lvbi9nbG9iYWwtdGltZS12YXJ5aW5nLXRyYW5zbWlzc2lvbi5odG1sKSB5IGVzdMOhIGVuIGNvbmNvcmRhbmNpYSBjb24gbG9zIHZhbG9yZXMgZGUgJFJfMCQgZGV0ZXJtaW5hZG9zIGluaWNpYWxtZW50ZSBlbiBDaGluYSB5LCBkdXJhbnRlIGJhc3RhbnRlIG3DoXMgdGllbXBvLCBlbiBJdGFsaWEuCgojIyMgQ29tbyBjdXJpb3NpZGFkCgogIERlIGVzdGEgc2VuY2lsbGEgYXByb3hpbWFjacOzbiBzZSBwdWVkZSBkZWR1Y2lyIHVuYSBjb25jbHVzacOzbiBkZSBpbnRlcsOpcyBlcGlkZW1pb2zDs2dpY286IHBhcmEgcmVkdWNpciBlbCAkUl8wJCBkZSBsYSAqQ09WSUQqIHBvciBkZWJham8gZGUgJDEkLCBkYWRvIHF1ZSBlcyBtdXkgZGlmw61jaWwgYWNlbGVyYXIgJFxnYW1tYSQsIHNlIHB1ZWRlIGRpc21pbnVpciAkUyQgKGNvbiB2YWN1bmFzKSBvIHJlZHVjaXIgJFxiZXRhJCAoY29uIHJlc3RyaWNjaW9uZXMgZGUgbW92aWxpZGFkKS4gIFNlZ8O6biBlbCB2YWxvciBjYWxjdWxhZG8gYXJyaWJhLCBiYXN0YXLDrWEgY29uIGRpdmlkaXIgYWxndW5vcyBkZSBlc3RvcyBkb3MgZWxlbWVudG9zIGVudHJlICQ1LjMkLCBlc3RvIGVzLCBlbiB1biA4MiAlIGFwcm94aW1hZGFtZW50ZS4gIEVzdG8gc2lnbmlmaWNhIHZhY3VuYXIgYWwgODIgJSBkZSBsYSBwb2JsYWNpw7NuIHN1c2NlcHRpYmxlLCBvIGJpZW4sIGxpbWl0YXIgbnVlc3Ryb3MgY29udGFjdG9zIGEgMSBkZSBjYWRhIDYgcGVyc29uYXMgY29uIGxhcyBxdWUgdHJhdGFtb3MgaGFiaXR1YWxtZW50ZS4gIEN1cmlvc2FtZW50ZSwgY29uIHNvbG8gbG9zIGRhdG9zIGRlIGxhcyBwcmltZXJhcyBzZW1hbmFzIHkgdW4gc2VuY2lsbG8gYW7DoWxpc2lzLCBoZW1vcyBhbGNhbnphZG8gbGFzIG1pc21hcyBjb25jbHVzaW9uZXMgcXVlIGFob3JhIGd1w61hbiBsYSBsdWNoYSBjb250cmEgZXN0YSBlcGlkZW1pYS4uLiDCoVNlZ3VybyBxdWUgaGEgc2lkbyBjYXN1YWxpZGFkISAKCgojIEVwaWRlbWlhIGNvbiByZWluZmVjY2nDs24KCiAgQ3VhbmRvIGxvcyByZWN1cGVyYWRvcyBwaWVyZGVuIGxhIGlubXVuaWRhZCB5IHNlIHZ1ZWx2ZW4gc3VjZXB0aWJsZXMgYWwgY2FibyBkZSBjaWVydG8gdGllbXBvLCBhcGFyZWNlIHVuYSBkaW7DoW1pY2EgY8OtY2xpY2EgY29ub2NpZGEgY29tbyAqb2xhcyouICBFc3RvIG9jdXJyZSBwb3JxdWUgc2UgaW50cm9kdWNlIHVuIG51ZXZvIGVsZW1lbnRvIGVuIGxhcyBlY3VhY2lvbmVzIHF1ZSBsYXMgY29udmllcnRlIGVuIHVuIG9zY2lsYWRvciBhbW9ydGlndWFkbzoKClxiZWdpbnthbGlnbn0KIFxmcmFje2RTfXtkdH0gJj0gXGFscGhhIFIgLSBcYmV0YSBTIEkgXFxbN3B0XQogXGZyYWN7ZEl9e2R0fSAmPSBcYmV0YSBTIEkgLSBcZ2FtbWEgSSBcXFs3cHRdCiBcZnJhY3tkUn17ZHR9ICY9IFxnYW1tYSBJIC0gXGFscGhhIFIKXGVuZHthbGlnbn0KCiAgRWwgbnVldm8gY29lZmljaWVudGUgJFxhbHBoYSQgZXMgaW52ZXJzYW1lbnRlIHByb3BvcmNpb25hbCBhbCB0aWVtcG8gcXVlIGR1cmEgbGEgaW5tdW5pZGFkIGRlIHVuICpyZWN1cGVyYWRvKiAoeWEgbm8gcHVlZGVuIHNlciBtdWVydG9zLCBjbGFybyBlc3TDoSkuCgogIFZlYW1vcyBsYSBkaW7DoW1pY2EgZGVsIHByaW1lciBlamVtcGxvLCBzdXBvbmllbmRvIHF1ZSBsYSBpbm11bmlkYWQgZHVyYSAyMCBzZW1hbmFzICgkXGFscGhhID0gMS8xNDAkIGTDrWFz4oG7wrkpCgpgYGB7ciBlY2hvPUZBTFNFfQp7CiMgSU5URUdSQUNJw5NOIERFIExBUyBFQ1VBQ0lPTkVTIFMuSS5SLiBjb24gcmVpbmZlY2Npw7NuCgojLS0tLSB0aWVtcG8gZmluYWwKdGllbXBvX2ZpbmFsIDwtIDYwMAp0IDwtIHNlcShmcm9tID0gMSwgdG8gPSB0aWVtcG9fZmluYWwpCgojLS0tLSBjb25kaWNpb25lcyBpbmljaWFsZXMgeSB2YWxvcmVzIGRlIGNvZWZpY2llbnRlcwpTIDwtIG51bWVyaWMoKQpTWzFdIDwtIDUwMDAwICMgc3VzY2VwdGlibGVzIGluaWNpYWxlcwpJIDwtIG51bWVyaWMoKQpJWzFdIDwtIDEgICAgICAjIGluZmVjdGFkb3MgaW5pY2lhbGVzClIgPC0gbnVtZXJpYygpClJbMV0gPC0gMCAgICAgICMgcmV0aXJhZG9zIGluaWNpYWxlcwpiZXRhIDwtIDguNTdFLTYKZ2FtYSA8LSAxLzcKYWxmYSA8LSAxLzE0MAoKIy0tLS0gYnVjbGUgaW50ZWdyYWNpw7NuIEV1bGVyCmZvciAoaSBpbiAxOihsZW5ndGgodCktMSkpewogIGNvbnRhZ2lvcyA8LSBiZXRhKlNbaV0qSVtpXQogIHJldGlyYWRvcyA8LSBnYW1hKklbaV0KICBkZXNpbm11bml6YWRvcyA8LSBhbGZhKlJbaV0KICBTW2krMV0gPC0gU1tpXSArIGRlc2lubXVuaXphZG9zIC0gY29udGFnaW9zCiAgSVtpKzFdIDwtIElbaV0gKyAoY29udGFnaW9zIC0gcmV0aXJhZG9zKQogIFJbaSsxXSA8LSBSW2ldICsgcmV0aXJhZG9zIC0gZGVzaW5tdW5pemFkb3MKfQoKIy0tLS0gZ3LDoWZpY28KcGxvdCh0LCBTLCB5bGltID0gYygwLCA1MDAwMCksIHR5cGUgPSAibCIsIGNvbCA9ICJncmVlbiIsIGx3ZCA9IDIsCiAgICAgeGxhYiA9ICJUSUVNUE8gKGTDrWFzKSIsIHlsYWIgPSAiSU5ESVZJRFVPUyIpCmxpbmVzKHQsIFIsIGNvbCA9ICJvcmFuZ2UiLCBsd2QgPSAyKQpsaW5lcyh0LCBJLCBjb2wgPSAicmVkIiwgbHdkID0gMikKbGVnZW5kKCJ0b3ByaWdodCIsIGMoIlMiLCJJIiwiUiIpLCBsd2QgPSAyLCBjb2wgPSBjKCJncmVlbiIsCiAgICAgICAgInJlZCIsICJvcmFuZ2UiKSwgY2V4ID0gMC44LCBidHkgPSAibiIpCn0KYGBgCiAgPGZpZ2NhcHRpb24+CiAgKipGaWd1cmEgNy4gRXBpZGVtaWEgY29uIHJlaW5mZWNjacOzbi4qKiAgQ3VhbmRvIGxvcyByZWN1cGVyYWRvcyBwaWVyZGVuIGxhIGlubXVuaWRhZCBzZSBwcm9kdWNlbiAqb2xlYWRhcyogZGUgaW5mZWN0YWRvcyBoYXN0YSBxdWUgY2VzYSBsYSBlcGlkZW1pYS4gIExhIGRpc3RhbmNpYSBlbnRyZSBsb3MgcGljb3MgZGUgZXN0YXMgb2xhcyB5IHN1IGludGVuc2lkYWQgc29uIHByb3BvcmNpb25hbGVzIGEgbGEgZHVyYWNpw7NuIGRlIGxhIGlubXVuaWRhZC4gIExvcyBjb2VmaWNpZW50ZXMgc29uIGxvcyBtaXNtb3MgZGUgbGEgRmlndXJhIDIsIG3DoXMgdW5hIHDDqXJkaWRhIGRlIGlubXVuaWRhZCBhIGxvcyAxNDAgZMOtYXMuCiAgPC9maWdjYXB0aW9uPgoKICBUYW1iacOpbiBzZSBwb2Ryw61hIGHDsWFkaXIgdW5hICp0YXNhIGRlIG1vcnRhbGlkYWQqIGFzb2NpYWRhIGNvbiBsYSBlbmZlcm1lZGFkLCBwYXJhIHF1ZSBlbCBhc3VudG8gZnVlc2UgbcOhcyByZWFsaXN0YSwgYXVucXVlIGVsIGludGVyw6lzIG1hdGVtw6F0aWNvIGVzIG3DrW5pbW8gcHVlcyBzb2xvIHNlIG1hbmlmaWVzdGEgZW4gdW5hIGNhw61kYSBleHBvbmVuY2lhbCBkZSBsb3MgcmVjdXBlcmFkb3MgeSBsYSBkaW7DoW1pY2Egb3NjaWxhbnRlIHNlZ3VpcsOtYSBzaWVuZG8gcHLDoWN0aWNhbWVudGUgbGEgbWlzbWEuCgoKCiMgTW9kZWxvIGJhc2FkbyBlbiBpbmRpdmlkdW9zCgo+KkxvIGRlIGFudGVzIGVyYSBzb2xvIHBhcmEgcmVjb3JkYXIgbG8gYsOhc2ljbyBkZWwgYXN1bnRvLiAgQXF1w60gZW1waWV6YSBsbyBpbnRlcmVzYW50ZS4qCgogIEN1YW5kbyBzZSBhZnJvbnRhIGVsIGZlbsOzbWVubyBlcGlkw6ltaWNvIGRlc2RlIGxhIG1lY8OhbmljYSBiYXNhZGEgZW4gaW5kaXZpZHVvcyBzZSBkaXNmcnV0YSBkZSB1bm9zIGF4aW9tYXMgbcOhcyBpbnR1aXRpdm9zOgoKLSBMb3MgaW5kaXZpZHVvcyBzZSBtdWV2ZW4gYWwgYXphciBwb3Igc3UgcHVlYmxvLgotIEN1YW5kbyB1biBpbmZlY3RhZG8gY29udGFjdGEgY29uIHVuIHN1c2NlcHRpYmxlIGxvIHB1ZWRlIGNvbnRhZ2lhciBjb24gdW5hIHByb2JhYmlsaWRhZCAkcCQuCi0gQWwgY2FibyBkZSBjaWVydG8gdGllbXBvLCBlbCBpbmZlY3RhZG8gc2UgcmVjdXBlcmEgeSB5YSBubyBjb250YWdpYSBtw6FzLgoKICBBcXXDrSB0ZW5lbW9zIHByb3BpZWRhZGVzIGluZGl2aWR1YWxlcywgZW4gdmV6IGRlIGxhcyBjb2xlY3RpdmFzIGRlbCBtb2RlbG8gZGlmZXJlbmNpYWwuICBObyBub3MgZW5yb2xsZW1vcyBtw6FzIHkgdmVhbW9zIGxhIHBlbMOtY3VsYSBkZWwgbW92aW1pZW50byBpbmRpdmlkdWFsIHkgbGEgdHJhbnNtaXNpw7NuIGRlIGxhIGVuZmVybWVkYWQ6Cgo8Y2VudGVyPjx2aWRlbyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgY29udHJvbHM+CiAgPHNvdXJjZSBzcmM9IlNJUjEubXA0IiB0eXBlPSJ2aWRlby9tcDQiPgo8L3ZpZGVvPjwvY2VudGVyPgogIDxmaWdjYXB0aW9uPgogICoqVsOtZGVvIDEuIERpbsOhbWljYSBlc3BhY2lhbCBkZSBsYSBlcGlkZW1pYS4qKiAgTG9zIHB1bnRvcyByb2pvcyByZXByZXNlbnRhbiBhIGxvcyBpbmZlY3RhZG9zIChjb21vIHNlIGVzcGVyYWJhKSBxdWUsIGN1YW5kbyBlbnRyYW4gZW4gY29udGFjdG8gY29uIGxvcyBzdXNjZXB0aWJsZXMgKHZlcmRlcykgbG9zIGluZmVjdGFuIGNvbiBjaWVydGEgcHJvYmFiaWxpZGFkLiAgQWwgY2FibyBkZSBhbGd1bm9zIGTDrWFzLCBsb3MgaW5mZWN0YWRvcyBzZSByZWN1cGVyYW4gKG5lZ3JvcykuCiAgPC9maWdjYXB0aW9uPgoKCiAgCmBgYHtyIHBhcmEgZ3JhYmFyIGVsIHbDrWRlbywgZWNobz1GQUxTRX0KCiMgTU9ERUxPIFMuSS5SLiBCQVNBRE8gRU4gSU5ESVZJRFVPUwojIE1vZGVsbyBiw6FzaWNvIHBhcmEgZXhwbGljYXIgZWwgZGVzYXJyb2xsbyBkZSB1bmEgZXBpZGVtaWEKIyAoY29uIHbDrWRlbykKCmxpYnJhcnkoYW5pbWF0aW9uKSAjIHBhcmEgaGFjZXIgbGEgcGVsw61jdWxhCnNhdmVHSUYoeyAjIHBhcmEgZ3VhcmRhciBsYSBzaW11bGFjacOzbiBlbiB1bmEgcGVsw61jdWxhCgojLS0tLSB0aWVtcG8gZmluYWwgeSB0YW1hw7FvIGRlbCBwdWVibG8KdGllbXBvX2ZpbmFsIDwtIDE1MAp4bWF4IDwtIDYwICAgICAgICAgICAgICAgICAgICAjIGFuY2hvIGRlbCBwdWVibG8gKGRlc2RlIHggPSAxIGhhc3RhIHggPSAxMDApCnltYXggPC0gNjAgICAgICAgICAgICAgICAgICAgICMgbGFyZ28gIiAgICAgIiAgICAoZGVzZGUgeSA9IDEgaGFzdGEgeSA9IDEwMCkKWFkgPC0gbWF0cml4KDBMLCB4bWF4LCB5bWF4KSAgICMgZWwgcHVlYmxvLCBwcm9waWFtZW50ZSBkaWNobwoKIy0tLS0gdmFyaWFibGVzClN0IDwtIGludGVnZXIoKQpJdCA8LSBpbnRlZ2VyKCkgICAgICAjIHBhcmEgZ3VhcmRhciBsb3MgdmFsb3JlcyBkZSBTLCBJLCBSIGEgY2FkYSB0aWVtcG8KUnQgPC0gaW50ZWdlcigpCgp4IDwtIGludGVnZXIoKSAgICAgICMgcG9zaWNpw7NuIHggZGUgbG9zIGluZGl2aWR1b3MKeSA8LSBpbnRlZ2VyKCkgICAgICAjICAgICAiICAgIHkgICAgICAiICAgICAgICIKZXN0YWRvIDwtIGludGVnZXIoKSAjIGVzdGFkbyBkZWwgaW5kaXZpZHVvICBTOjAgIEk6MSAgUjoyCmNvbnZhbCA8LSBpbnRlZ2VyKCkgIyB0aWVtcG8gcXVlIGxsZXZhIGRlIGNvbnZhbGVjZW5jaWEKCiMtLS0tIGNvZWZpY2llbnRlcyB5IGRlbcOhcwpwIDwtIDAuOSAgICAgICAgICAgICAgICAgIyBwcm9iYWJpbGlkYWQgZGUgY29udGFnaW8KZCA8LSAxNSAgICAgICAgICAgICAgICAgICMgZHVyYWNpw7NuIGRlIGxhIGVuZmVybWVkYWQKbW92IDwtIGMoLTEsIDAsIDEpICAgICAgICMgbW92aW1pZW50byAodW5hIGNhc2lsbGEgcGFjYWxhbykKcG12IDwtIGMoMC40LCAwLjIsIDAuNCkgICMgcHJvYmFiaWxpZGFkIGRlIG1vdmVyc2UgZW4gY2FkYSBkaXJlY2Npw7NuIFhZCgojLS0tLSBjb25kaWNpb25lcyBpbmljaWFsZXMKTiA8LSAxMDAwICAgICAgIyBuw7ptZXJvIHRvdGFsIGRlIGluZGl2aWR1b3MKUyA8LSBOIC0gMSAgICAgIyBzdXNjZXB0aWJsZXMgaW5pY2lhbGVzCkkgPC0gMSAgICAgICAgICMgaW5mZWN0YWRvcyAgICAgICIKUiA8LSAwICAgICAgICAgIyByZXRpcmFkb3MgICAgICAgIgpTdFsxXSA8LSBTCkl0WzFdIDwtIEkKUnRbMV0gPC0gUgoKIyBMb2NhbGl6YXIgYSBsb3MgaW5kaXZpZHVvcwpmb3IoaSBpbiAxOk4pewogIHhbaV0gPC0gZmxvb3IoeG1heCpydW5pZigxKSArIDEpICAjIHBlbnNhbmRvIGVuIEMuLi4KICB5W2ldIDwtIGZsb29yKHltYXgqcnVuaWYoMSkgKyAxKQogIGVzdGFkb1tpXSA8LSAwCiAgWFlbeFtpXSwgeVtpXV0gPC0gaSAgICAgICAgICAgICAgIyBsb2NhbGl6YXIgYWwgw7psdGltbyBlbiBsbGVnYXIKfQoKIyBpbmZlY3RhZG9zIGVuIG1lZGlvLCBwYSBxdWUgc2UgdmVhIG1lw7NuCmZvcihpIGluIDE6SSl7CiAgeFtpXSA8LSBmbG9vcih4bWF4KjAuNSArIDEpICAKICB5W2ldIDwtIGZsb29yKHltYXgqMC41ICsgMSkKICBlc3RhZG9baV0gPC0gMQogIFhZW3hbaV0sIHlbaV1dIDwtIGkgICAgICAgICAgICAgIAogIGVzdGFkb1tpXSA8LSAxCiAgY29udmFsW2ldIDwtIDAKfQoKIyBncsOhZmljbyBpbmljaWFsCnBhcihwdHkgPSAicyIsIG1hciA9IGMoMSwgMSwgMSwgMSksIHhheHQgPSAibiIsIHlheHQgPSAibiIsIAogICAgeGF4cyA9ICJpIiwgeWF4cz0iaSIpCnBsb3QoeCwgeSwgeGxpbSA9IGMoMSwgeG1heCksIHlsaW0gPSBjKDEsIHltYXgpLCBwY2ggPSAyMCwgY29sID0gMyAtIGVzdGFkbywKICAgICAgIG1haW4gPSBicXVvdGUodDouKDEpfiIgICAiflM6LihTKX4iICAgIn5JOi4oSSl+IiAgICJ+UjouKFIpKSwKICAgICAgIHhsYWIgPSAieCIsIHlsYWIgPSAieSIpCmFuaS5yZWNvcmQoKSAjIGdyYWJhIGNvbW8gZm90b2dyYW1hCgoKIy0tLS0gQlVDTEUgREVMIFRJRU1QTwpmb3IodCBpbiAyOnRpZW1wb19maW5hbCl7CiAgCiAgWFkxIDwtIFhZICAgICAjIHBhcmEgaGFjZXIgbGFzIG9wZXJhY2lvbmVzIHNpbmNyb25pemFkYXMKICBYWVtdIDwtIDBMICAgICMgYm9ycmFyIGxhIG1hdHJpegogIAogICMtLS0tIGJ1Y2xlIGRlIGxvcyBpbmRpdmlkdW9zCiAgZm9yKGkgaW4gMTpOKXsKICAgIAogICAgIyBjb21wcm9iYXIgY29udmFsZWNlbmNpYQogICAgaWYoZXN0YWRvW2ldID09IDEpIHsjIHNvbG8gcGFyYSBpbmZlY3RhZG9zCiAgICAgIGNvbnZhbFtpXSA8LSBjb252YWxbaV0gKyAxCiAgICAgIGlmKGNvbnZhbFtpXSA+IGQpIHsjIHNlIHJlY3VwZXJhCiAgICAgICAgZXN0YWRvW2ldIDwtIDIKICAgICAgICBJIDwtIEkgLSAxCiAgICAgICAgUiA8LSBSICsgMQogICAgICB9CiAgICB9CiAgICAKICAgICMgbW92aW1pZW50byBhbCBhemFyCiAgICBkeCA8LSBzYW1wbGUobW92LCBzaXplID0gMSwgcHJvYiA9IHBtdikKICAgIGR5IDwtIHNhbXBsZShtb3YsIHNpemUgPSAxLCBwcm9iID0gcG12KQogICAgeFtpXSA8LSB4W2ldICsgZHgKICAgIHlbaV0gPC0geVtpXSArIGR5CiAgICBpZih4W2ldID4geG1heCkge3hbaV0gPC0gMX0gIyBwb3Igc2kgc2Ugc2FsZSBwb3IgbG9zIGxhZG9zCiAgICBpZih4W2ldIDwgMSkge3hbaV0gPC0geG1heH0KICAgIGlmKHlbaV0gPiB5bWF4KSB7eVtpXSA8LSAxfSAjIHBvciBzaSBzZSBzYWxlIHBvciBhcnJpYmEvYWJham8KICAgIGlmKHlbaV0gPCAxKSB7eVtpXSA8LSB5bWF4fQogICAgICAKICAgICMgZGV0ZWN0YXIgZW5jdWVudHJvCiAgICBvIDwtIFhZMVt4W2ldLCB5W2ldXQogICAgaWYobyA+IDApIHsKICAgICAgaWYobyAhPSBpKSB7ICMgc2UgaGEgZW5jb250cmFkbyBjb24gb3RybwogICAgICAgICMgc2UgbG8gcGVnbwogICAgICAgIGlmKChlc3RhZG9baV0gPT0gMSkgJiAoZXN0YWRvW29dID09IDApKXsKICAgICAgICAgIGlmKHJ1bmlmKDEpIDwgcCl7CiAgICAgICAgICAgIGVzdGFkb1tvXSA8LSAxCiAgICAgICAgICAgIGNvbnZhbFtvXSA8LSAwCiAgICAgICAgICAgIEkgPC0gSSArIDEKICAgICAgICAgICAgUyA8LSBTIC0gMQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjIG1lIGxvIHBlZ2EKICAgICAgICBpZigoZXN0YWRvW29dID09IDEpICYgKGVzdGFkb1tpXSA9PSAwKSl7CiAgICAgICAgICBpZihydW5pZigxKSA8IHApewogICAgICAgICAgICBlc3RhZG9baV0gPC0gMQogICAgICAgICAgICBjb252YWxbaV0gPC0gMAogICAgICAgICAgICBJIDwtIEkgKyAxCiAgICAgICAgICAgIFMgPC0gUyAtIDEKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIAogICAgWFlbeFtpXSwgeVtpXV0gPC0gaSAgICMgYWN0dWFsaXphciBsb2NhbGl6YWNpw7NuCiAgfQogIAogIFN0W3RdIDwtIFMKICBJdFt0XSA8LSBJICAgICMgZ3VhcmRhciB2YWxvcmVzCiAgUnRbdF0gPC0gUgogIAogICMgZ3LDoWZpY28KICBwbG90KHgsIHksIHhsaW0gPSBjKDEsIHhtYXgpLCB5bGltID0gYygxLCB5bWF4KSwgcGNoID0gMjAsIGNvbCA9IDMgLSBlc3RhZG8sCiAgICAgICBtYWluID0gYnF1b3RlKHQ6Lih0KX4iICAgIn5TOi4oUyl+IiAgICJ+STouKEkpfiIgICAiflI6LihSKSksCiAgICAgICB4bGFiID0gIngiLCB5bGFiID0gInkiKQoKfQogICBhbmkucmVjb3JkKCkgIyBncmFiYSBjb21vIGZvdG9ncmFtYQogIH0sIGludGVydmFsID0gLjIsIG1vdmllLm5hbWUgPSAiU19JX1JfMDEuZ2lmIiwgYW5pLndpZHRoID0gMjU2LCBhbmkuaGVpZ2h0ID0gMjU2KQogIAoKCgoKIy0tLS0gZ3LDoWZpY28gZmluYWwKcGxvdChTdCwgdHlwZSA9ICJsIiwgbHdkID0gMiwgY29sID0gImdyZWVuIiwgeWxpbSA9IGMoMCxOKSwgeGxhYiA9ICJUaWVtcG8iLCB5bGFiID0gIkluZGl2aWR1b3MiKQpsaW5lcyhJdCwgbHdkID0gMiwgY29sID0gInJlZCIpCmxpbmVzKFJ0LCBsd2QgPSAyKQpsZWdlbmQoMCwgTi8yLCBjKCJTIiwgIkkiLCAiUiIpLCBsdHkgPSBjKDEsIDEsIDEpLCBsd2QgPSBjKDIsIDIsIDIpLCBjb2wgPSBjKDMsIDIsIDEpLCBidHkgPSAibiIpCgpgYGAKICA8ZmlnY2FwdGlvbj4KICAqKkZpZ3VyYSA4LiBTaW11bGFjacOzbiBiYXNhZGEgZW4gaW5kaXZpZHVvcy4qKiAgQ29uIGxvcyB0aXR1YmVvcyBkZWJpZG9zIGFsIGF6YXIsIGVsIHBhdHLDs24gZGUgbGEgZXBpZGVtaWEgYXBhcmVjZSBjbGFyYW1lbnRlLgogIDwvZmlnY2FwdGlvbj4KCiAgQXF1w60gZGViYWpvIGVsIGPDs2RpZ286CgpgYGB7ciBldmFsID0gRkFMU0V9CnsKIyBNT0RFTE8gUy5JLlIuIEJBU0FETyBFTiBJTkRJVklEVU9TCiMgTW9kZWxvIGLDoXNpY28gcGFyYSBleHBsaWNhciBlbCBkZXNhcnJvbGxvIGRlIHVuYSBlcGlkZW1pYQojIChzaW4gdsOtZGVvKQoKCiMtLS0tIHRpZW1wbyBmaW5hbCB5IHRhbWHDsW8gZGVsIHB1ZWJsbwp0aWVtcG9fZmluYWwgPC0gMTUwCnhtYXggPC0gNjAgICAgICAgICAgICAgICAgICAgICMgYW5jaG8gZGVsIHB1ZWJsbyAoZGVzZGUgeCA9IDEgaGFzdGEgeCA9IDEwMCkKeW1heCA8LSA2MCAgICAgICAgICAgICAgICAgICAgIyBsYXJnbyAiICAgICAiICAgIChkZXNkZSB5ID0gMSBoYXN0YSB5ID0gMTAwKQpYWSA8LSBtYXRyaXgoMEwsIHhtYXgsIHltYXgpICAgIyBlbCBwdWVibG8sIHByb3BpYW1lbnRlIGRpY2hvCgojLS0tLSB2YXJpYWJsZXMKU3QgPC0gaW50ZWdlcigpCkl0IDwtIGludGVnZXIoKSAgICAgICMgcGFyYSBndWFyZGFyIGxvcyB2YWxvcmVzIGRlIFMsIEksIFIgYSBjYWRhIHRpZW1wbwpSdCA8LSBpbnRlZ2VyKCkKCnggPC0gaW50ZWdlcigpICAgICAgIyBwb3NpY2nDs24geCBkZSBsb3MgaW5kaXZpZHVvcwp5IDwtIGludGVnZXIoKSAgICAgICMgICAgICIgICAgeSAgICAgICIgICAgICAgIgplc3RhZG8gPC0gaW50ZWdlcigpICMgZXN0YWRvIGRlbCBpbmRpdmlkdW8gIFM6MCAgSToxICBSOjIKY29udmFsIDwtIGludGVnZXIoKSAjIHRpZW1wbyBxdWUgbGxldmEgZGUgY29udmFsZWNlbmNpYQoKIy0tLS0gY29lZmljaWVudGVzIHkgZGVtw6FzCnAgPC0gMC45ICAgICAgICAgICAgICAgICAjIHByb2JhYmlsaWRhZCBkZSBjb250YWdpbwpkIDwtIDE1ICAgICAgICAgICAgICAgICAgIyBkdXJhY2nDs24gZGUgbGEgZW5mZXJtZWRhZAptb3YgPC0gYygtMSwgMCwgMSkgICAgICAgIyBtb3ZpbWllbnRvICh1bmEgY2FzaWxsYSBwYWNhbGFvKQpwbXYgPC0gYygwLjQsIDAuMiwgMC40KSAgIyBwcm9iYWJpbGlkYWQgZGUgbW92ZXJzZSBlbiBjYWRhIGRpcmVjY2nDs24gWFkKCiMtLS0tIGNvbmRpY2lvbmVzIGluaWNpYWxlcwpOIDwtIDEwMDAgICAgICAjIG7Dum1lcm8gdG90YWwgZGUgaW5kaXZpZHVvcwpTIDwtIE4gLSAxICAgICAjIHN1c2NlcHRpYmxlcyBpbmljaWFsZXMKSSA8LSAxICAgICAgICAgIyBpbmZlY3RhZG9zICAgICAgIgpSIDwtIDAgICAgICAgICAjIHJldGlyYWRvcyAgICAgICAiClN0WzFdIDwtIFMKSXRbMV0gPC0gSQpSdFsxXSA8LSBSCgojIExvY2FsaXphciBhIGxvcyBpbmRpdmlkdW9zCmZvcihpIGluIDE6Til7CiAgeFtpXSA8LSBmbG9vcih4bWF4KnJ1bmlmKDEpICsgMSkgICMgcGVuc2FuZG8gZW4gQy4uLgogIHlbaV0gPC0gZmxvb3IoeW1heCpydW5pZigxKSArIDEpCiAgZXN0YWRvW2ldIDwtIDAKICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgICAgICAgICAgICAjIGxvY2FsaXphciBhbCDDumx0aW1vIGVuIGxsZWdhcgp9CgojIGluZmVjdGFkb3MKZm9yKGkgaW4gMTpJKXsKICB4W2ldIDwtIGZsb29yKHhtYXgqMC41ICsgMSkgIAogIHlbaV0gPC0gZmxvb3IoeW1heCowLjUgKyAxKQogIGVzdGFkb1tpXSA8LSAxCiAgWFlbeFtpXSwgeVtpXV0gPC0gaSAgICAgICAgICAgICAgCiAgZXN0YWRvW2ldIDwtIDEKICBjb252YWxbaV0gPC0gMAp9CgojLS0tLSBCVUNMRSBERUwgVElFTVBPCmZvcih0IGluIDI6dGllbXBvX2ZpbmFsKXsKICAKICBYWTEgPC0gWFkgICAgICMgcGFyYSBoYWNlciBsYXMgb3BlcmFjaW9uZXMgc2luY3Jvbml6YWRhcwogIFhZW10gPC0gMEwgICAgIyBib3JyYXIgbGEgbWF0cml6CiAgCiAgIy0tLS0gYnVjbGUgZGUgbG9zIGluZGl2aWR1b3MKICBmb3IoaSBpbiAxOk4pewogICAgCiAgICAjIGNvbXByb2JhciBjb252YWxlY2VuY2lhCiAgICBpZihlc3RhZG9baV0gPT0gMSkgeyMgc29sbyBwYXJhIGluZmVjdGFkb3MKICAgICAgY29udmFsW2ldIDwtIGNvbnZhbFtpXSArIDEKICAgICAgaWYoY29udmFsW2ldID4gZCkgeyMgc2UgcmVjdXBlcmEKICAgICAgICBlc3RhZG9baV0gPC0gMgogICAgICAgIEkgPC0gSSAtIDEKICAgICAgICBSIDwtIFIgKyAxCiAgICAgIH0KICAgIH0KICAgIAogICAgIyBtb3ZpbWllbnRvIGFsIGF6YXIKICAgIGR4IDwtIHNhbXBsZShtb3YsIHNpemUgPSAxLCBwcm9iID0gcG12KQogICAgZHkgPC0gc2FtcGxlKG1vdiwgc2l6ZSA9IDEsIHByb2IgPSBwbXYpCiAgICB4W2ldIDwtIHhbaV0gKyBkeAogICAgeVtpXSA8LSB5W2ldICsgZHkKICAgIGlmKHhbaV0gPiB4bWF4KSB7eFtpXSA8LSAxfSAjIHBvciBzaSBzZSBzYWxlIHBvciBsb3MgbGFkb3MKICAgIGlmKHhbaV0gPCAxKSB7eFtpXSA8LSB4bWF4fQogICAgaWYoeVtpXSA+IHltYXgpIHt5W2ldIDwtIDF9ICMgcG9yIHNpIHNlIHNhbGUgcG9yIGFycmliYS9hYmFqbwogICAgaWYoeVtpXSA8IDEpIHt5W2ldIDwtIHltYXh9CiAgICAgIAogICAgIyBkZXRlY3RhciBlbmN1ZW50cm8KICAgIG8gPC0gWFkxW3hbaV0sIHlbaV1dCiAgICBpZihvID4gMCkgewogICAgICBpZihvICE9IGkpIHsgIyBzZSBoYSBlbmNvbnRyYWRvIGNvbiBvdHJvCiAgICAgICAgIyBzZSBsbyBwZWdvCiAgICAgICAgaWYoKGVzdGFkb1tpXSA9PSAxKSAmIChlc3RhZG9bb10gPT0gMCkpewogICAgICAgICAgaWYocnVuaWYoMSkgPCBwKXsKICAgICAgICAgICAgZXN0YWRvW29dIDwtIDEKICAgICAgICAgICAgY29udmFsW29dIDwtIDAKICAgICAgICAgICAgSSA8LSBJICsgMQogICAgICAgICAgICBTIDwtIFMgLSAxCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICMgbWUgbG8gcGVnYQogICAgICAgIGlmKChlc3RhZG9bb10gPT0gMSkgJiAoZXN0YWRvW2ldID09IDApKXsKICAgICAgICAgIGlmKHJ1bmlmKDEpIDwgcCl7CiAgICAgICAgICAgIGVzdGFkb1tpXSA8LSAxCiAgICAgICAgICAgIGNvbnZhbFtpXSA8LSAwCiAgICAgICAgICAgIEkgPC0gSSArIDEKICAgICAgICAgICAgUyA8LSBTIC0gMQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogICAgCiAgICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgIyBhY3R1YWxpemFyIGxvY2FsaXphY2nDs24KICB9CiAgCiAgU3RbdF0gPC0gUwogIEl0W3RdIDwtIEkgICAgIyBndWFyZGFyIHZhbG9yZXMKICBSdFt0XSA8LSBSCiAgCn0KCiMtLS0tIGdyw6FmaWNvIGZpbmFsCnBsb3QoU3QsIHR5cGUgPSAibCIsIGx3ZCA9IDIsIGNvbCA9ICJncmVlbiIsIHlsaW0gPSBjKDAsTiksIHhsYWIgPSAiVGllbXBvIiwgeWxhYiA9ICJJbmRpdmlkdW9zIikKbGluZXMoSXQsIGx3ZCA9IDIsIGNvbCA9ICJyZWQiKQpsaW5lcyhSdCwgbHdkID0gMikKbGVnZW5kKDAsIE4vMiwgYygiUyIsICJJIiwgIlIiKSwgbHR5ID0gYygxLCAxLCAxKSwgbHdkID0gYygyLCAyLCAyKSwgY29sID0gYygzLCAyLCAxKSwgYnR5ID0gIm4iKQp9CmBgYAoKICBObyBtZSBjb252ZW5jZSBtdWNobyBlbCBhc3VudG8gZGUgbGFzIG1hdHJpY2VzLCBwb3JxdWUgZWwgw7psdGltbyBlbiBsbGVnYXIgYWwgc2l0aW8gZXMgZWwgcXVlIG1hcmNhIGxhcyBwcm9waWVkYWRlcy4gIFZhbW9zIGEgZGVqYXJsbyBhc8OtIHBvciBlbCBtb21lbnRvLCBwb3NpYmxlbWVudGUgbm8gdGVuZ2EgbXVjaGEgaW1wb3J0YW5jaWEgZW4gcHVlYmxvcyBlbnJhcmVjaWRvcywgcGVybyBsYSBtb3NjYSBlc3TDoSBlbiBsYSBvcmVqYS4KCiAgVmVhbW9zIGVsIHByb21lZGlvIGRlIDEwMCBzaW11bGFjaW9uZXMKCmBgYHtyIGVjaG89RkFMU0V9CnsKIyBNT0RFTE8gUy5JLlIuIEJBU0FETyBFTiBJTkRJVklEVU9TCiMgTW9kZWxvIGLDoXNpY28gcGFyYSBleHBsaWNhciBlbCBkZXNhcnJvbGxvIGRlIHVuYSBlcGlkZW1pYQojIFBST01FRElPIERFIE1VQ0hBUyBTSU1VTEFDSU9ORVMKCiMtLS0tIHRpZW1wbyBmaW5hbCB5IHRhbWHDsW8gZGVsIHB1ZWJsbwp0aWVtcG9fZmluYWwgPC0gMjAwCnhtYXggPC0gNjAgICAgICAgICAgICAgICAgICAgICMgYW5jaG8gZGVsIHB1ZWJsbyAoZGVzZGUgeCA9IDEgaGFzdGEgeCA9IDEwMCkKeW1heCA8LSA2MCAgICAgICAgICAgICAgICAgICAgIyBsYXJnbyAiICAgICAiICAgIChkZXNkZSB5ID0gMSBoYXN0YSB5ID0gMTAwKQpYWSA8LSBtYXRyaXgoMEwsIHhtYXgsIHltYXgpICAgIyBlbCBwdWVibG8sIHByb3BpYW1lbnRlIGRpY2hvCgojLS0tLSB2YXJpYWJsZXMKU3QgPC0gaW50ZWdlcigpCkl0IDwtIGludGVnZXIoKSAgICAgICMgcGFyYSBndWFyZGFyIGxvcyB2YWxvcmVzIGRlIFMsIEksIFIgYSBjYWRhIHRpZW1wbwpSdCA8LSBpbnRlZ2VyKCkKCnggPC0gaW50ZWdlcigpICAgICAgIyBwb3NpY2nDs24geCBkZSBsb3MgaW5kaXZpZHVvcwp5IDwtIGludGVnZXIoKSAgICAgICMgICAgICIgICAgeSAgICAgICIgICAgICAgIgplc3RhZG8gPC0gaW50ZWdlcigpICMgZXN0YWRvIGRlbCBpbmRpdmlkdW8gIFM6MCAgSToxICBSOjIKY29udmFsIDwtIGludGVnZXIoKSAjIHRpZW1wbyBxdWUgbGxldmEgZGUgY29udmFsZWNlbmNpYQoKIy0tLS0gY29lZmljaWVudGVzIHkgZGVtw6FzCnAgPC0gMC45ICAgICAgICAgICAgICAgICAjIHByb2JhYmlsaWRhZCBkZSBjb250YWdpbwpkIDwtIDE1ICAgICAgICAgICAgICAgICAgIyBkdXJhY2nDs24gZGUgbGEgZW5mZXJtZWRhZAptb3YgPC0gYygtMSwgMCwgMSkgICAgICAgIyBtb3ZpbWllbnRvICh1bmEgY2FzaWxsYSBwYWNhbGFvKQpwbXYgPC0gYygwLjQsIDAuMiwgMC40KSAgIyBwcm9iYWJpbGlkYWQgZGUgbW92ZXJzZSBlbiBjYWRhIGRpcmVjY2nDs24gWFkKCiMtLS0tIDEwMCBSRVBFVElDSU9ORVMKcmVwZXRpY2lvbmVzIDwtIDEwMAp0YWJsYV9TIDwtIGRhdGEuZnJhbWUobWF0cml4KE5BLCBucm93ID0gdGllbXBvX2ZpbmFsLCBuY29sID0gMCkpCnRhYmxhX0kgPC0gZGF0YS5mcmFtZShtYXRyaXgoTkEsIG5yb3cgPSB0aWVtcG9fZmluYWwsIG5jb2wgPSAwKSkKdGFibGFfUiA8LSBkYXRhLmZyYW1lKG1hdHJpeChOQSwgbnJvdyA9IHRpZW1wb19maW5hbCwgbmNvbCA9IDApKQoKZm9yKHJlcCBpbiAxOnJlcGV0aWNpb25lcyl7CiAgICAKICAgICMtLS0tIGNvbmRpY2lvbmVzIGluaWNpYWxlcwogICAgTiA8LSAxMDAwICAgICAgIyBuw7ptZXJvIHRvdGFsIGRlIGluZGl2aWR1b3MKICAgIFMgPC0gTiAtIDEgICAgICMgc3VzY2VwdGlibGVzIGluaWNpYWxlcwogICAgSSA8LSAxICAgICAgICAgIyBpbmZlY3RhZG9zICAgICAgIgogICAgUiA8LSAwICAgICAgICAgIyByZXRpcmFkb3MgICAgICAgIgogICAgU3RbMV0gPC0gUwogICAgSXRbMV0gPC0gSQogICAgUnRbMV0gPC0gUgogICAgCiAgICAjIExvY2FsaXphciBhIGxvcyBpbmRpdmlkdW9zCiAgICBYWVtdIDwtIDBMICAgICMgYm9ycmFyIGxhIG1hdHJpegogICAgZm9yKGkgaW4gMTpOKXsKICAgICAgeFtpXSA8LSBmbG9vcih4bWF4KnJ1bmlmKDEpICsgMSkgICMgcGVuc2FuZG8gZW4gQy4uLgogICAgICB5W2ldIDwtIGZsb29yKHltYXgqcnVuaWYoMSkgKyAxKQogICAgICBlc3RhZG9baV0gPC0gMAogICAgICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgICAgICAgICAgICAjIGxvY2FsaXphciBhbCDDumx0aW1vIGVuIGxsZWdhcgogICAgfQogICAgCiAgICAjIGluZmVjdGFkb3MKICAgIGZvcihpIGluIDE6SSl7CiAgICAgIHhbaV0gPC0gZmxvb3IoeG1heCpydW5pZigxKSArIDEpICAKICAgICAgeVtpXSA8LSBmbG9vcih5bWF4KnJ1bmlmKDEpICsgMSkKICAgICAgZXN0YWRvW2ldIDwtIDEKICAgICAgWFlbeFtpXSwgeVtpXV0gPC0gaSAgICAgICAgICAgICAgCiAgICAgIGVzdGFkb1tpXSA8LSAxCiAgICAgIGNvbnZhbFtpXSA8LSAwCiAgICB9CiAgICAKICAgICMtLS0tIEJVQ0xFIERFTCBUSUVNUE8KICAgIGZvcih0IGluIDI6dGllbXBvX2ZpbmFsKXsKICAgICAgCiAgICAgIFhZMSA8LSBYWSAgICAgIyBwYXJhIGhhY2VyIGxhcyBvcGVyYWNpb25lcyBzaW5jcm9uaXphZGFzCiAgICAgIFhZW10gPC0gMEwgICAgIyBib3JyYXIgbGEgbWF0cml6CiAgICAgIAogICAgICAjLS0tLSBidWNsZSBkZSBsb3MgaW5kaXZpZHVvcwogICAgICBmb3IoaSBpbiAxOk4pewogICAgICAgIAogICAgICAgICMgY29tcHJvYmFyIGNvbnZhbGVjZW5jaWEKICAgICAgICBpZihlc3RhZG9baV0gPT0gMSkgeyMgc29sbyBwYXJhIGluZmVjdGFkb3MKICAgICAgICAgIGNvbnZhbFtpXSA8LSBjb252YWxbaV0gKyAxCiAgICAgICAgICBpZihjb252YWxbaV0gPiBkKSB7IyBzZSByZWN1cGVyYQogICAgICAgICAgICBlc3RhZG9baV0gPC0gMgogICAgICAgICAgICBJIDwtIEkgLSAxCiAgICAgICAgICAgIFIgPC0gUiArIDEKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgIyBtb3ZpbWllbnRvIGFsIGF6YXIKICAgICAgICBkeCA8LSBzYW1wbGUobW92LCBzaXplID0gMSkKICAgICAgICBkeSA8LSBzYW1wbGUobW92LCBzaXplID0gMSkKICAgICAgICB4W2ldIDwtIHhbaV0gKyBkeAogICAgICAgIHlbaV0gPC0geVtpXSArIGR5CiAgICAgICAgaWYoeFtpXSA+IHhtYXgpIHt4W2ldIDwtIDF9ICMgcG9yIHNpIHNlIHNhbGUgcG9yIGxvcyBsYWRvcwogICAgICAgIGlmKHhbaV0gPCAxKSB7eFtpXSA8LSB4bWF4fQogICAgICAgIGlmKHlbaV0gPiB5bWF4KSB7eVtpXSA8LSAxfSAjIHBvciBzaSBzZSBzYWxlIHBvciBhcnJpYmEvYWJham8KICAgICAgICBpZih5W2ldIDwgMSkge3lbaV0gPC0geW1heH0KICAgICAgICAgIAogICAgICAgICMgZGV0ZWN0YXIgZW5jdWVudHJvCiAgICAgICAgbyA8LSBYWTFbeFtpXSwgeVtpXV0KICAgICAgICBpZihvID4gMCkgewogICAgICAgICAgaWYobyAhPSBpKSB7ICMgc2UgaGEgZW5jb250cmFkbyBjb24gb3RybwogICAgICAgICAgICAjIHNlIGxvIHBlZ28KICAgICAgICAgICAgaWYoKGVzdGFkb1tpXSA9PSAxKSAmIChlc3RhZG9bb10gPT0gMCkpewogICAgICAgICAgICAgIGlmKHJ1bmlmKDEpIDwgcCl7CiAgICAgICAgICAgICAgICBlc3RhZG9bb10gPC0gMQogICAgICAgICAgICAgICAgY29udmFsW29dIDwtIDAKICAgICAgICAgICAgICAgIEkgPC0gSSArIDEKICAgICAgICAgICAgICAgIFMgPC0gUyAtIDEKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgIyBtZSBsbyBwZWdhCiAgICAgICAgICAgIGlmKChlc3RhZG9bb10gPT0gMSkgJiAoZXN0YWRvW2ldID09IDApKXsKICAgICAgICAgICAgICBpZihydW5pZigxKSA8IHApewogICAgICAgICAgICAgICAgZXN0YWRvW2ldIDwtIDEKICAgICAgICAgICAgICAgIGNvbnZhbFtpXSA8LSAwCiAgICAgICAgICAgICAgICBJIDwtIEkgKyAxCiAgICAgICAgICAgICAgICBTIDwtIFMgLSAxCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIFhZW3hbaV0sIHlbaV1dIDwtIGkgICAjIGFjdHVhbGl6YXIgbG9jYWxpemFjacOzbgogICAgICB9CiAgICAgIAogICAgICBTdFt0XSA8LSBTCiAgICAgIEl0W3RdIDwtIEkgICAgIyBndWFyZGFyIHZhbG9yZXMKICAgICAgUnRbdF0gPC0gUgogICAgICAKICAgIH0KICAgIAogICAgdGFibGFfUyA8LSBjYmluZCh0YWJsYV9TLCBTdCkKICAgIHRhYmxhX0kgPC0gY2JpbmQodGFibGFfSSwgSXQpICAgIyBhw7FhZGltb3MgbGEgc2ltdWxhY2nDs24KICAgIHRhYmxhX1IgPC0gY2JpbmQodGFibGFfUiwgUnQpCgp9CgojLS0tLSByZXN1bWVuIGRlIGxhcyByZXBldGljaW9uZXMKU19tZWRpbyA8LSByb3dNZWFucyh0YWJsYV9TKQpJX21lZGlvIDwtIHJvd01lYW5zKHRhYmxhX0kpClJfbWVkaW8gPC0gcm93TWVhbnModGFibGFfUikKCiMtLS0tIGdyw6FmaWNvIG1lZGlhcwpwbG90KFNfbWVkaW8sIHR5cGUgPSAibCIsIGx3ZCA9IDIsIGNvbCA9ICJncmVlbiIsIHlsaW0gPSBjKDAsTiksIHhsYWIgPSAiVGllbXBvIiwgeWxhYiA9ICJJbmRpdmlkdW9zIikKbGluZXMoSV9tZWRpbywgbHdkID0gMiwgY29sID0gInJlZCIpCmxpbmVzKFJfbWVkaW8sIGx3ZCA9IDIpCmxlZ2VuZCgwLCBOLzIsIGMoIlMiLCAiSSIsICJSIiksIGx0eSA9IGMoMSwgMSwgMSksIGx3ZCA9IGMoMiwgMiwgMiksIGNvbCA9IGMoMywgMiwgMSksIGJ0eSA9ICJuIikKfQpgYGAKICA8ZmlnY2FwdGlvbj4KICAqKkZpZ3VyYSA5LiBQcm9tZWRpbyBkZSAxMDAgc2ltdWxhY2lvbmVzLioqICBTZSBwYXJlY2UgYWwgbW9kZWxvIGRpZmVyZW5jaWFsIHBlZWVyb29vLi4uCiAgPC9maWdjYXB0aW9uPgoKICBFbCBpbmljaW8gZGUgbGEgZXBpZGVtaWEgZXMgZGVtYXNpYWRvIGxpbmVhbC4gIFBvZHLDrWEgdHJhdGFyc2UgZGU6CgoxKSAqRXhwbGljYWNpw7NuIHNlc3VkYToqIEF1bnF1ZSBoYXlhIG11Y2hvcyBzdXNjZXB0aWJsZXMsIGNhZGEgaW5mZWN0YWRvIHNvbG8gcHVlZGUgYWNjZWRlciBhIGxvcyBxdWUgZXN0w6FuIG3DoXMgY2VyY2EgZGUgw6lsLCBxdWUgZXMgdW5hIGNhbnRpZGFkIGNvbnN0YW50ZS4gIEVzdG8gc2UgdHJhZHVjZSBlbiB1biAqZnJlbnRlIGRlIGxsYW1hKiBxdWUgYXZhbnphIHNvYnJlIHVuIG1hciBzZSBzdXNjZXB0aWJsZXMgZGVqYW5kbyB0cmFzIHPDrSB1biBib3NxdWUgZGUgcmVjdXBlcmFkb3MuCjIpICpBcnRlZmFjdG86KiBBbCB1c2FyIGxhIG1pc21hIG1hdHJpeiBwYXJhIHRvZG9zIGxvcyBpbmRpdmlkdW9zLCBwdWVkZW4gZW5tYXNjYXJhcnNlIGluZmVjdGFkb3MgcG9yIHNvbGFwYW1pZW50byBjb24gcmVjdXBlcmFkb3MuICBFc3RvIHNlIHBvZHLDrWEgZXZpdGFyIGNvbiBtYXRyaWNlcyBpbmRlcGVuZGllbnRlcyBwYXJhICRTJCBlICRJJCB5LCB5YSBwdWVzdG9zLCB0YW1iacOpbiBwYXJhICRSJC4KCiAgQW50ZXMgZGUgcG9uZXJtZSBjb24gbGFzIG1hdHJpY2VzIGluZGVwZW5kaWVudGVzLCBjb25maXJtZW1vcyBxdWUgc2UgdHJhdGEgZGVsIGVmZWN0byBmcmVudGUgZGUgbGxhbWEuICBQYXJhIGV2aXRhcmxvLCBjcmVvIHF1ZSBiYXN0YSBjb24gZGlzbWludWlyIGxhIHByb2JhYmlsaWRhZCBkZSBjb250YWdpbyB5IGF1bWVudGFyIGxhIGR1cmFjacOzbiBkZSBsYSBlbmZlcm1lZGFkLiAgVmVhbW9zOgoKYGBge3IgZWNobz1GQUxTRX0KewojIE1PREVMTyBTLkkuUi4gQkFTQURPIEVOIElORElWSURVT1MKIyBNb2RlbG8gYsOhc2ljbyBwYXJhIGV4cGxpY2FyIGVsIGRlc2Fycm9sbG8gZGUgdW5hIGVwaWRlbWlhCiMgUFJPTUVESU8gREUgTVVDSEFTIFNJTVVMQUNJT05FUwoKIy0tLS0gdGllbXBvIGZpbmFsIHkgdGFtYcOxbyBkZWwgcHVlYmxvCnRpZW1wb19maW5hbCA8LSA3MDAKeG1heCA8LSA2MCAgICAgICAgICAgICAgICAgICAgIyBhbmNobyBkZWwgcHVlYmxvIChkZXNkZSB4ID0gMSBoYXN0YSB4ID0gMTAwKQp5bWF4IDwtIDYwICAgICAgICAgICAgICAgICAgICAjIGxhcmdvICIgICAgICIgICAgKGRlc2RlIHkgPSAxIGhhc3RhIHkgPSAxMDApClhZIDwtIG1hdHJpeCgwTCwgeG1heCwgeW1heCkgICAjIGVsIHB1ZWJsbywgcHJvcGlhbWVudGUgZGljaG8KCiMtLS0tIHZhcmlhYmxlcwpTdCA8LSBpbnRlZ2VyKCkKSXQgPC0gaW50ZWdlcigpICAgICAgIyBwYXJhIGd1YXJkYXIgbG9zIHZhbG9yZXMgZGUgUywgSSwgUiBhIGNhZGEgdGllbXBvClJ0IDwtIGludGVnZXIoKQoKeCA8LSBpbnRlZ2VyKCkgICAgICAjIHBvc2ljacOzbiB4IGRlIGxvcyBpbmRpdmlkdW9zCnkgPC0gaW50ZWdlcigpICAgICAgIyAgICAgIiAgICB5ICAgICAgIiAgICAgICAiCmVzdGFkbyA8LSBpbnRlZ2VyKCkgIyBlc3RhZG8gZGVsIGluZGl2aWR1byAgUzowICBJOjEgIFI6Mgpjb252YWwgPC0gaW50ZWdlcigpICMgdGllbXBvIHF1ZSBsbGV2YSBkZSBjb252YWxlY2VuY2lhCgojLS0tLSBjb2VmaWNpZW50ZXMgeSBkZW3DoXMKcCA8LSAwLjEgICAgICAgICAgICAgICAgICMgcHJvYmFiaWxpZGFkIGRlIGNvbnRhZ2lvCmQgPC0gMTAwICAgICAgICAgICAgICAgICAjIGR1cmFjacOzbiBkZSBsYSBlbmZlcm1lZGFkCm1vdiA8LSBjKC0xLCAwLCAxKSAgICAgICAjIG1vdmltaWVudG8gKHVuYSBjYXNpbGxhIHBhY2FsYW8pCnBtdiA8LSBjKDAuNCwgMC4yLCAwLjQpICAjIHByb2JhYmlsaWRhZCBkZSBtb3ZlcnNlIGVuIGNhZGEgZGlyZWNjacOzbiBYWQoKIy0tLS0gMTAwIFJFUEVUSUNJT05FUwpyZXBldGljaW9uZXMgPC0gMTAwCnRhYmxhX1MgPC0gZGF0YS5mcmFtZShtYXRyaXgoTkEsIG5yb3cgPSB0aWVtcG9fZmluYWwsIG5jb2wgPSAwKSkKdGFibGFfSSA8LSBkYXRhLmZyYW1lKG1hdHJpeChOQSwgbnJvdyA9IHRpZW1wb19maW5hbCwgbmNvbCA9IDApKQp0YWJsYV9SIDwtIGRhdGEuZnJhbWUobWF0cml4KE5BLCBucm93ID0gdGllbXBvX2ZpbmFsLCBuY29sID0gMCkpCgpmb3IocmVwIGluIDE6cmVwZXRpY2lvbmVzKXsKICAgIAogICAgIy0tLS0gY29uZGljaW9uZXMgaW5pY2lhbGVzCiAgICBOIDwtIDEwMDAgICAgICAjIG7Dum1lcm8gdG90YWwgZGUgaW5kaXZpZHVvcwogICAgUyA8LSBOIC0gMSAgICAgIyBzdXNjZXB0aWJsZXMgaW5pY2lhbGVzCiAgICBJIDwtIDEgICAgICAgICAjIGluZmVjdGFkb3MgICAgICAiCiAgICBSIDwtIDAgICAgICAgICAjIHJldGlyYWRvcyAgICAgICAiCiAgICBTdFsxXSA8LSBTCiAgICBJdFsxXSA8LSBJCiAgICBSdFsxXSA8LSBSCiAgICAKICAgICMgTG9jYWxpemFyIGEgbG9zIGluZGl2aWR1b3MKICAgIFhZW10gPC0gMEwgICAgIyBib3JyYXIgbGEgbWF0cml6CiAgICBmb3IoaSBpbiAxOk4pewogICAgICB4W2ldIDwtIGZsb29yKHhtYXgqcnVuaWYoMSkgKyAxKSAgIyBwZW5zYW5kbyBlbiBDLi4uCiAgICAgIHlbaV0gPC0gZmxvb3IoeW1heCpydW5pZigxKSArIDEpCiAgICAgIGVzdGFkb1tpXSA8LSAwCiAgICAgIFhZW3hbaV0sIHlbaV1dIDwtIGkgICAgICAgICAgICAgICMgbG9jYWxpemFyIGFsIMO6bHRpbW8gZW4gbGxlZ2FyCiAgICB9CiAgICAKICAgICMgaW5mZWN0YWRvcwogICAgZm9yKGkgaW4gMTpJKXsKICAgICAgeFtpXSA8LSBmbG9vcih4bWF4KnJ1bmlmKDEpICsgMSkgIAogICAgICB5W2ldIDwtIGZsb29yKHltYXgqcnVuaWYoMSkgKyAxKQogICAgICBlc3RhZG9baV0gPC0gMQogICAgICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgICAgICAgICAgICAKICAgICAgZXN0YWRvW2ldIDwtIDEKICAgICAgY29udmFsW2ldIDwtIDAKICAgIH0KICAgIAogICAgIy0tLS0gQlVDTEUgREVMIFRJRU1QTwogICAgZm9yKHQgaW4gMjp0aWVtcG9fZmluYWwpewogICAgICAKICAgICAgWFkxIDwtIFhZICAgICAjIHBhcmEgaGFjZXIgbGFzIG9wZXJhY2lvbmVzIHNpbmNyb25pemFkYXMKICAgICAgWFlbXSA8LSAwTCAgICAjIGJvcnJhciBsYSBtYXRyaXoKICAgICAgCiAgICAgICMtLS0tIGJ1Y2xlIGRlIGxvcyBpbmRpdmlkdW9zCiAgICAgIGZvcihpIGluIDE6Til7CiAgICAgICAgCiAgICAgICAgIyBjb21wcm9iYXIgY29udmFsZWNlbmNpYQogICAgICAgIGlmKGVzdGFkb1tpXSA9PSAxKSB7IyBzb2xvIHBhcmEgaW5mZWN0YWRvcwogICAgICAgICAgY29udmFsW2ldIDwtIGNvbnZhbFtpXSArIDEKICAgICAgICAgIGlmKGNvbnZhbFtpXSA+IGQpIHsjIHNlIHJlY3VwZXJhCiAgICAgICAgICAgIGVzdGFkb1tpXSA8LSAyCiAgICAgICAgICAgIEkgPC0gSSAtIDEKICAgICAgICAgICAgUiA8LSBSICsgMQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAjIG1vdmltaWVudG8gYWwgYXphcgogICAgICAgIGR4IDwtIHNhbXBsZShtb3YsIHNpemUgPSAxKQogICAgICAgIGR5IDwtIHNhbXBsZShtb3YsIHNpemUgPSAxKQogICAgICAgIHhbaV0gPC0geFtpXSArIGR4CiAgICAgICAgeVtpXSA8LSB5W2ldICsgZHkKICAgICAgICBpZih4W2ldID4geG1heCkge3hbaV0gPC0gMX0gIyBwb3Igc2kgc2Ugc2FsZSBwb3IgbG9zIGxhZG9zCiAgICAgICAgaWYoeFtpXSA8IDEpIHt4W2ldIDwtIHhtYXh9CiAgICAgICAgaWYoeVtpXSA+IHltYXgpIHt5W2ldIDwtIDF9ICMgcG9yIHNpIHNlIHNhbGUgcG9yIGFycmliYS9hYmFqbwogICAgICAgIGlmKHlbaV0gPCAxKSB7eVtpXSA8LSB5bWF4fQogICAgICAgICAgCiAgICAgICAgIyBkZXRlY3RhciBlbmN1ZW50cm8KICAgICAgICBvIDwtIFhZMVt4W2ldLCB5W2ldXQogICAgICAgIGlmKG8gPiAwKSB7CiAgICAgICAgICBpZihvICE9IGkpIHsgIyBzZSBoYSBlbmNvbnRyYWRvIGNvbiBvdHJvCiAgICAgICAgICAgICMgc2UgbG8gcGVnbwogICAgICAgICAgICBpZigoZXN0YWRvW2ldID09IDEpICYgKGVzdGFkb1tvXSA9PSAwKSl7CiAgICAgICAgICAgICAgaWYocnVuaWYoMSkgPCBwKXsKICAgICAgICAgICAgICAgIGVzdGFkb1tvXSA8LSAxCiAgICAgICAgICAgICAgICBjb252YWxbb10gPC0gMAogICAgICAgICAgICAgICAgSSA8LSBJICsgMQogICAgICAgICAgICAgICAgUyA8LSBTIC0gMQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAjIG1lIGxvIHBlZ2EKICAgICAgICAgICAgaWYoKGVzdGFkb1tvXSA9PSAxKSAmIChlc3RhZG9baV0gPT0gMCkpewogICAgICAgICAgICAgIGlmKHJ1bmlmKDEpIDwgcCl7CiAgICAgICAgICAgICAgICBlc3RhZG9baV0gPC0gMQogICAgICAgICAgICAgICAgY29udmFsW2ldIDwtIDAKICAgICAgICAgICAgICAgIEkgPC0gSSArIDEKICAgICAgICAgICAgICAgIFMgPC0gUyAtIDEKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgWFlbeFtpXSwgeVtpXV0gPC0gaSAgICMgYWN0dWFsaXphciBsb2NhbGl6YWNpw7NuCiAgICAgIH0KICAgICAgCiAgICAgIFN0W3RdIDwtIFMKICAgICAgSXRbdF0gPC0gSSAgICAjIGd1YXJkYXIgdmFsb3JlcwogICAgICBSdFt0XSA8LSBSCiAgICAgIAogICAgfQogICAgCiAgICB0YWJsYV9TIDwtIGNiaW5kKHRhYmxhX1MsIFN0KQogICAgdGFibGFfSSA8LSBjYmluZCh0YWJsYV9JLCBJdCkgICAjIGHDsWFkaW1vcyBsYSBzaW11bGFjacOzbgogICAgdGFibGFfUiA8LSBjYmluZCh0YWJsYV9SLCBSdCkKCn0KCiMtLS0tIHJlc3VtZW4gZGUgbGFzIHJlcGV0aWNpb25lcwpTX21lZGlvIDwtIHJvd01lYW5zKHRhYmxhX1MpCklfbWVkaW8gPC0gcm93TWVhbnModGFibGFfSSkKUl9tZWRpbyA8LSByb3dNZWFucyh0YWJsYV9SKQoKIy0tLS0gZ3LDoWZpY28gbWVkaWFzCnBsb3QoU19tZWRpbywgdHlwZSA9ICJsIiwgbHdkID0gMiwgY29sID0gImdyZWVuIiwgeWxpbSA9IGMoMCxOKSwgeGxhYiA9ICJUaWVtcG8iLCB5bGFiID0gIkluZGl2aWR1b3MiKQpsaW5lcyhJX21lZGlvLCBsd2QgPSAyLCBjb2wgPSAicmVkIikKbGluZXMoUl9tZWRpbywgbHdkID0gMikKbGVnZW5kKDAsIE4vMiwgYygiUyIsICJJIiwgIlIiKSwgbHR5ID0gYygxLCAxLCAxKSwgbHdkID0gYygyLCAyLCAyKSwgY29sID0gYygzLCAyLCAxKSwgYnR5ID0gIm4iKQp9CmBgYAogIDxmaWdjYXB0aW9uPgogICoqRmlndXJhIDEwLiBFdml0YXIgZWwgZnJlbnRlIGRlIGxsYW1hLioqICBFZmVjdGl2YW1lbnRlLCBjdWFuZG8gc2UgcmVkdWNlIGxhIHByb2JhYmlsaWRhZCBkZSBjb250YWdpbyB5IGF1bWVudGEgZWwgdGllbXBvIGRlIGNvbnZhbGVjZW5jaWEgZGVzYXBhcmVjZSBlbCBlZmVjdG8gKmZyZW50ZSBkZSBsbGFtYSouICBBaG9yYSBsbyBzb3NwZWNob3NvIGVzIGxhIGNhw61kYSBzaW3DqXRyaWNhLCBxdWUgbm8gY29uY3VlcmRhIGNvbiBsbyBlc3BlcmFkbyBzZWfDum4gdW4gcHJvY2VzbyBleHBvbmVuY2lhbC4KICA8L2ZpZ2NhcHRpb24+CgogIMK/U2Vyw6EgdW4gZWZlY3RvIHRhcGFkZXJhIGRlIGxvcyByZWN1cGVyYWRvcz8gIFNpIGhheSBtdWNob3MsIHB1ZWRlbiBlbmN1YnJpciBhIGxvcyBzdXNjZXB0aWJsZXMuICBWZWFtb3MgbGEgc2ltdWxhY2nDs24gcXVpdMOhbmRvbG9zOgoKYGBge3IgZWNobz1GQUxTRX0KewojIE1PREVMTyBTLkkuUi4gQkFTQURPIEVOIElORElWSURVT1MKIyBNb2RlbG8gYsOhc2ljbyBwYXJhIGV4cGxpY2FyIGVsIGRlc2Fycm9sbG8gZGUgdW5hIGVwaWRlbWlhCiMgUFJPTUVESU8gREUgTVVDSEFTIFNJTVVMQUNJT05FUyBZIE9CVklBTkRPIEEgTE9TIFJFQ1VQRVJBRE9TCgojLS0tLSB0aWVtcG8gZmluYWwgeSB0YW1hw7FvIGRlbCBwdWVibG8KdGllbXBvX2ZpbmFsIDwtIDcwMAp4bWF4IDwtIDYwICAgICAgICAgICAgICAgICAgICAjIGFuY2hvIGRlbCBwdWVibG8gKGRlc2RlIHggPSAxIGhhc3RhIHggPSAxMDApCnltYXggPC0gNjAgICAgICAgICAgICAgICAgICAgICMgbGFyZ28gIiAgICAgIiAgICAoZGVzZGUgeSA9IDEgaGFzdGEgeSA9IDEwMCkKWFkgPC0gbWF0cml4KDBMLCB4bWF4LCB5bWF4KSAgICMgZWwgcHVlYmxvLCBwcm9waWFtZW50ZSBkaWNobwoKIy0tLS0gdmFyaWFibGVzClN0IDwtIGludGVnZXIoKQpJdCA8LSBpbnRlZ2VyKCkgICAgICAjIHBhcmEgZ3VhcmRhciBsb3MgdmFsb3JlcyBkZSBTLCBJLCBSIGEgY2FkYSB0aWVtcG8KUnQgPC0gaW50ZWdlcigpCgp4IDwtIGludGVnZXIoKSAgICAgICMgcG9zaWNpw7NuIHggZGUgbG9zIGluZGl2aWR1b3MKeSA8LSBpbnRlZ2VyKCkgICAgICAjICAgICAiICAgIHkgICAgICAiICAgICAgICIKZXN0YWRvIDwtIGludGVnZXIoKSAjIGVzdGFkbyBkZWwgaW5kaXZpZHVvICBTOjAgIEk6MSAgUjoyCmNvbnZhbCA8LSBpbnRlZ2VyKCkgIyB0aWVtcG8gcXVlIGxsZXZhIGRlIGNvbnZhbGVjZW5jaWEKCiMtLS0tIGNvZWZpY2llbnRlcyB5IGRlbcOhcwpwIDwtIDAuMSAgICAgICAgICAgICAgICAgIyBwcm9iYWJpbGlkYWQgZGUgY29udGFnaW8KZCA8LSAxMDAgICAgICAgICAgICAgICAgICAjIGR1cmFjacOzbiBkZSBsYSBlbmZlcm1lZGFkCm1vdiA8LSBjKC0xLCAwLCAxKSAgICAgICAjIG1vdmltaWVudG8gKHVuYSBjYXNpbGxhIHBhY2FsYW8pCnBtdiA8LSBjKDAuNCwgMC4yLCAwLjQpICAjIHByb2JhYmlsaWRhZCBkZSBtb3ZlcnNlIGVuIGNhZGEgZGlyZWNjacOzbiBYWQoKIy0tLS0gMTAwIFJFUEVUSUNJT05FUwpyZXBldGljaW9uZXMgPC0gNDAKdGFibGFfUyA8LSBkYXRhLmZyYW1lKG1hdHJpeChOQSwgbnJvdyA9IHRpZW1wb19maW5hbCwgbmNvbCA9IDApKQp0YWJsYV9JIDwtIGRhdGEuZnJhbWUobWF0cml4KE5BLCBucm93ID0gdGllbXBvX2ZpbmFsLCBuY29sID0gMCkpCnRhYmxhX1IgPC0gZGF0YS5mcmFtZShtYXRyaXgoTkEsIG5yb3cgPSB0aWVtcG9fZmluYWwsIG5jb2wgPSAwKSkKCmZvcihyZXAgaW4gMTpyZXBldGljaW9uZXMpewogICAgCiAgICAjLS0tLSBjb25kaWNpb25lcyBpbmljaWFsZXMKICAgIE4gPC0gMTAwMCAgICAgICMgbsO6bWVybyB0b3RhbCBkZSBpbmRpdmlkdW9zCiAgICBJIDwtIDEgICAgICAgICAjIGluZmVjdGFkb3MgaW5pY2lhbGVzCiAgICBTIDwtIE4gLSBJICAgICAjIHN1c2NlcHRpYmxlcyAgICAiCiAgICBSIDwtIDAgICAgICAgICAjIHJldGlyYWRvcyAgICAgICAiCiAgICBTdFsxXSA8LSBTCiAgICBJdFsxXSA8LSBJCiAgICBSdFsxXSA8LSBSCiAgICAKICAgICMgTG9jYWxpemFyIGEgbG9zIGluZGl2aWR1b3MKICAgIFhZW10gPC0gMEwgICAgIyBib3JyYXIgbGEgbWF0cml6CiAgICBmb3IoaSBpbiAxOk4pewogICAgICB4W2ldIDwtIGZsb29yKHhtYXgqcnVuaWYoMSkgKyAxKSAgIyBwZW5zYW5kbyBlbiBDLi4uCiAgICAgIHlbaV0gPC0gZmxvb3IoeW1heCpydW5pZigxKSArIDEpCiAgICAgIGVzdGFkb1tpXSA8LSAwCiAgICAgIFhZW3hbaV0sIHlbaV1dIDwtIGkgICAgICAgICAgICAgICMgbG9jYWxpemFyIGFsIMO6bHRpbW8gZW4gbGxlZ2FyCiAgICB9CiAgICAKICAgICMgaW5mZWN0YWRvcwogICAgZm9yKGkgaW4gMTpJKXsKICAgICAgeFtpXSA8LSBmbG9vcih4bWF4KnJ1bmlmKDEpICsgMSkgIAogICAgICB5W2ldIDwtIGZsb29yKHltYXgqcnVuaWYoMSkgKyAxKQogICAgICBlc3RhZG9baV0gPC0gMQogICAgICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgICAgICAgICAgICAKICAgICAgZXN0YWRvW2ldIDwtIDEKICAgICAgY29udmFsW2ldIDwtIDAKICAgIH0KICAgIAogICAgIy0tLS0gQlVDTEUgREVMIFRJRU1QTwogICAgZm9yKHQgaW4gMjp0aWVtcG9fZmluYWwpewogICAgICAKICAgICAgWFkxIDwtIFhZICAgICAjIHBhcmEgaGFjZXIgbGFzIG9wZXJhY2lvbmVzIHNpbmNyb25pemFkYXMKICAgICAgWFlbXSA8LSAwTCAgICAjIGJvcnJhciBsYSBtYXRyaXoKICAgICAgCiAgICAgICMtLS0tIGJ1Y2xlIGRlIGxvcyBpbmRpdmlkdW9zCiAgICAgIGZvcihpIGluIDE6Til7CiAgICAgICAgCiAgICAgICAgIyBvYnZpYXIgbG9zIHJlY3VwZXJhZG9zCiAgICAgICAgaWYoZXN0YWRvW2ldICE9IDIpewogICAgICAgIAogICAgICAgICAgIyBjb21wcm9iYXIgY29udmFsZWNlbmNpYQogICAgICAgICAgaWYoZXN0YWRvW2ldID09IDEpIHsjIHNvbG8gcGFyYSBpbmZlY3RhZG9zCiAgICAgICAgICAgIGNvbnZhbFtpXSA8LSBjb252YWxbaV0gKyAxCiAgICAgICAgICAgIGlmKGNvbnZhbFtpXSA+IGQpIHsjIHNlIHJlY3VwZXJhCiAgICAgICAgICAgICAgZXN0YWRvW2ldIDwtIDIKICAgICAgICAgICAgICBJIDwtIEkgLSAxCiAgICAgICAgICAgICAgUiA8LSBSICsgMQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAKICAgICAgICAgICMgbW92aW1pZW50byBhbCBhemFyCiAgICAgICAgICBkeCA8LSBzYW1wbGUobW92LCBzaXplID0gMSkKICAgICAgICAgIGR5IDwtIHNhbXBsZShtb3YsIHNpemUgPSAxKQogICAgICAgICAgeFtpXSA8LSB4W2ldICsgZHgKICAgICAgICAgIHlbaV0gPC0geVtpXSArIGR5CiAgICAgICAgICBpZih4W2ldID4geG1heCkge3hbaV0gPC0gMX0gIyBwb3Igc2kgc2Ugc2FsZSBwb3IgbG9zIGxhZG9zCiAgICAgICAgICBpZih4W2ldIDwgMSkge3hbaV0gPC0geG1heH0KICAgICAgICAgIGlmKHlbaV0gPiB5bWF4KSB7eVtpXSA8LSAxfSAjIHBvciBzaSBzZSBzYWxlIHBvciBhcnJpYmEvYWJham8KICAgICAgICAgIGlmKHlbaV0gPCAxKSB7eVtpXSA8LSB5bWF4fQogICAgICAgICAgICAKICAgICAgICAgICMgZGV0ZWN0YXIgZW5jdWVudHJvCiAgICAgICAgICBvIDwtIFhZMVt4W2ldLCB5W2ldXQogICAgICAgICAgaWYobyA+IDApIHsKICAgICAgICAgICAgaWYobyAhPSBpKSB7ICMgc2UgaGEgZW5jb250cmFkbyBjb24gb3RybwogICAgICAgICAgICAgICMgc2UgbG8gcGVnbwogICAgICAgICAgICAgIGlmKChlc3RhZG9baV0gPT0gMSkgJiAoZXN0YWRvW29dID09IDApKXsKICAgICAgICAgICAgICAgIGlmKHJ1bmlmKDEpIDwgcCl7CiAgICAgICAgICAgICAgICAgIGVzdGFkb1tvXSA8LSAxCiAgICAgICAgICAgICAgICAgIGNvbnZhbFtvXSA8LSAwCiAgICAgICAgICAgICAgICAgIEkgPC0gSSArIDEKICAgICAgICAgICAgICAgICAgUyA8LSBTIC0gMQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAjIG1lIGxvIHBlZ2EKICAgICAgICAgICAgICBpZigoZXN0YWRvW29dID09IDEpICYgKGVzdGFkb1tpXSA9PSAwKSl7CiAgICAgICAgICAgICAgICBpZihydW5pZigxKSA8IHApewogICAgICAgICAgICAgICAgICBlc3RhZG9baV0gPC0gMQogICAgICAgICAgICAgICAgICBjb252YWxbaV0gPC0gMAogICAgICAgICAgICAgICAgICBJIDwtIEkgKyAxCiAgICAgICAgICAgICAgICAgIFMgPC0gUyAtIDEKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIAogICAgICAgICAgWFlbeFtpXSwgeVtpXV0gPC0gaSAgICMgYWN0dWFsaXphciBsb2NhbGl6YWNpw7NuCiAgICAgICAgfQogICAgICB9CiAgICAgIAogICAgICBTdFt0XSA8LSBTCiAgICAgIEl0W3RdIDwtIEkgICAgIyBndWFyZGFyIHZhbG9yZXMKICAgICAgUnRbdF0gPC0gUgogICAgICAKICAgIH0KICAgIAogICAgdGFibGFfUyA8LSBjYmluZCh0YWJsYV9TLCBTdCkKICAgIHRhYmxhX0kgPC0gY2JpbmQodGFibGFfSSwgSXQpICAgIyBhw7FhZGltb3MgbGEgc2ltdWxhY2nDs24KICAgIHRhYmxhX1IgPC0gY2JpbmQodGFibGFfUiwgUnQpCgp9CgojLS0tLSByZXN1bWVuIGRlIGxhcyByZXBldGljaW9uZXMKU19tZWRpbyA8LSByb3dNZWFucyh0YWJsYV9TKQpJX21lZGlvIDwtIHJvd01lYW5zKHRhYmxhX0kpClJfbWVkaW8gPC0gcm93TWVhbnModGFibGFfUikKCiMtLS0tIGdyw6FmaWNvIG1lZGlhcwpwbG90KFNfbWVkaW8sIHR5cGUgPSAibCIsIGx3ZCA9IDIsIGNvbCA9ICJncmVlbiIsIHlsaW0gPSBjKDAsTiksIHhsYWIgPSAiVGllbXBvIiwgeWxhYiA9ICJJbmRpdmlkdW9zIikKbGluZXMoSV9tZWRpbywgbHdkID0gMiwgY29sID0gInJlZCIpCmxpbmVzKFJfbWVkaW8sIGx3ZCA9IDIpCmxlZ2VuZCgwLCBOLzIsIGMoIlMiLCAiSSIsICJSIiksIGx0eSA9IGMoMSwgMSwgMSksIGx3ZCA9IGMoMiwgMiwgMiksIGNvbCA9IGMoMywgMiwgMSksIGJ0eSA9ICJuIikKfQpgYGAKICA8ZmlnY2FwdGlvbj4KICAqKkZpZ3VyYSAxMS4gU2luIHJlY3VwZXJhZG9zLioqICBFc2Nhc2EgZGlmZXJlbmNpYSwgYXPDrSBxdWUgbm8gbWVyZWNlIGxhIHBlbmEsIHBvcnF1ZSBkZXNwdcOpcyBlbCBjw7NkaWdvIHNlIHZvbHZlcsOhIG3DoXMgY29tcGxpY2FkbyB5IG11Y2hvIG1lbm9zIGVsZWdhbnRlLgogIDwvZmlnY2FwdGlvbj4KCgrCv1NlcsOhIHVuIGVmZWN0byBkZSBsYSBjb252YWxlY2VuY2lhLCBxdWUgbm8gdGllbmUgdW4gdmFsb3IgY29uc3RhbnRlPyAgVmVhbW9zIGPDs21vIHNlIGRpc3RyaWJ1eWUgbGEgY29udmFsZWNlbmNpYToKCmBgYHtyIHBhcmEgZ3JhYmFyIGVsIHbDrWRlbyBjb24gbGEgY29udmFsZWNlbmNpYSwgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KCiMgTU9ERUxPIFMuSS5SLiBCQVNBRE8gRU4gSU5ESVZJRFVPUwojIE1vZGVsbyBiw6FzaWNvIHBhcmEgZXhwbGljYXIgZWwgZGVzYXJyb2xsbyBkZSB1bmEgZXBpZGVtaWEKIyAoY29uIHbDrWRlbykKCmxpYnJhcnkoYW5pbWF0aW9uKSAjIHBhcmEgaGFjZXIgbGEgcGVsw61jdWxhCnNhdmVHSUYoeyAjIHBhcmEgZ3VhcmRhciBsYSBzaW11bGFjacOzbiBlbiB1bmEgcGVsw61jdWxhCgojLS0tLSB0aWVtcG8gZmluYWwgeSB0YW1hw7FvIGRlbCBwdWVibG8KdGllbXBvX2ZpbmFsIDwtIDcwMAp4bWF4IDwtIDYwICAgICAgICAgICAgICAgICAgICAjIGFuY2hvIGRlbCBwdWVibG8gKGRlc2RlIHggPSAxIGhhc3RhIHggPSAxMDApCnltYXggPC0gNjAgICAgICAgICAgICAgICAgICAgICMgbGFyZ28gIiAgICAgIiAgICAoZGVzZGUgeSA9IDEgaGFzdGEgeSA9IDEwMCkKWFkgPC0gbWF0cml4KDBMLCB4bWF4LCB5bWF4KSAgICMgZWwgcHVlYmxvLCBwcm9waWFtZW50ZSBkaWNobwoKIy0tLS0gdmFyaWFibGVzClN0IDwtIGludGVnZXIoKQpJdCA8LSBpbnRlZ2VyKCkgICAgICAjIHBhcmEgZ3VhcmRhciBsb3MgdmFsb3JlcyBkZSBTLCBJLCBSIGEgY2FkYSB0aWVtcG8KUnQgPC0gaW50ZWdlcigpCgp4IDwtIGludGVnZXIoKSAgICAgICMgcG9zaWNpw7NuIHggZGUgbG9zIGluZGl2aWR1b3MKeSA8LSBpbnRlZ2VyKCkgICAgICAjICAgICAiICAgIHkgICAgICAiICAgICAgICIKZXN0YWRvIDwtIGludGVnZXIoKSAjIGVzdGFkbyBkZWwgaW5kaXZpZHVvICBTOjAgIEk6MSAgUjoyCmNvbnZhbCA8LSBpbnRlZ2VyKCkgIyB0aWVtcG8gcXVlIGxsZXZhIGRlIGNvbnZhbGVjZW5jaWEKCiMtLS0tIGNvZWZpY2llbnRlcyB5IGRlbcOhcwpwIDwtIDAuMSAgICAgICAgICAgICAgICAgIyBwcm9iYWJpbGlkYWQgZGUgY29udGFnaW8KZCA8LSAxMDAgICAgICAgICAgICAgICAgICAjIGR1cmFjacOzbiBkZSBsYSBlbmZlcm1lZGFkCm1vdiA8LSBjKC0xLCAwLCAxKSAgICAgICAjIG1vdmltaWVudG8gKHVuYSBjYXNpbGxhIHBhY2FsYW8pCnBtdiA8LSBjKDAuNCwgMC4yLCAwLjQpICAjIHByb2JhYmlsaWRhZCBkZSBtb3ZlcnNlIGVuIGNhZGEgZGlyZWNjacOzbiBYWQoKIy0tLS0gY29uZGljaW9uZXMgaW5pY2lhbGVzCk4gPC0gMTAwMCAgICAgICMgbsO6bWVybyB0b3RhbCBkZSBpbmRpdmlkdW9zClMgPC0gTiAtIDEgICAgICMgc3VzY2VwdGlibGVzIGluaWNpYWxlcwpJIDwtIDEgICAgICAgICAjIGluZmVjdGFkb3MgICAgICAiClIgPC0gMCAgICAgICAgICMgcmV0aXJhZG9zICAgICAgICIKU3RbMV0gPC0gUwpJdFsxXSA8LSBJClJ0WzFdIDwtIFIKCiMgTG9jYWxpemFyIGEgbG9zIGluZGl2aWR1b3MKZm9yKGkgaW4gMTpOKXsKICB4W2ldIDwtIGZsb29yKHhtYXgqcnVuaWYoMSkgKyAxKSAgIyBwZW5zYW5kbyBlbiBDLi4uCiAgeVtpXSA8LSBmbG9vcih5bWF4KnJ1bmlmKDEpICsgMSkKICBlc3RhZG9baV0gPC0gMAogIFhZW3hbaV0sIHlbaV1dIDwtIGkgICAgICAgICAgICAgICMgbG9jYWxpemFyIGFsIMO6bHRpbW8gZW4gbGxlZ2FyCn0KCiMgaW5mZWN0YWRvcyBlbiBtZWRpbywgcGEgcXVlIHNlIHZlYSBtZcOzbgpmb3IoaSBpbiAxOkkpewogIHhbaV0gPC0gZmxvb3IoeG1heCowLjUgKyAxKSAgCiAgeVtpXSA8LSBmbG9vcih5bWF4KjAuNSArIDEpCiAgZXN0YWRvW2ldIDwtIDEKICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgICAgICAgICAgICAKICBlc3RhZG9baV0gPC0gMQogIGNvbnZhbFtpXSA8LSAwCn0KCiMgZ3LDoWZpY28gaW5pY2lhbApwYXIocHR5ID0gInMiLCBtYXIgPSBjKDEsIDEsIDEsIDEpLCB4YXh0ID0gIm4iLCB5YXh0ID0gIm4iLAogICAgeGF4cyA9ICJpIiwgeWF4cz0iaSIpCiMgcGxvdCh4LCB5LCB4bGltID0gYygxLCB4bWF4KSwgeWxpbSA9IGMoMSwgeW1heCksIHBjaCA9IDIwLCBjb2wgPSAzIC0gZXN0YWRvLAojICAgICAgICBtYWluID0gYnF1b3RlKHQ6LigxKX4iICAgIn5TOi4oUyl+IiAgICJ+STouKEkpfiIgICAiflI6LihSKSksCiMgICAgICAgIHhsYWIgPSAieCIsIHlsYWIgPSAieSIpCnBsb3QodGFibGUoY29udmFsKSwgeGxpbSA9IGMoMSwgZCksIHlsaW0gPSBjKDAsIDUwKSkKYW5pLnJlY29yZCgpICMgZ3JhYmEgY29tbyBmb3RvZ3JhbWEKCgojLS0tLSBCVUNMRSBERUwgVElFTVBPCmZvcih0IGluIDI6dGllbXBvX2ZpbmFsKXsKICAKICBYWTEgPC0gWFkgICAgICMgcGFyYSBoYWNlciBsYXMgb3BlcmFjaW9uZXMgc2luY3Jvbml6YWRhcwogIFhZW10gPC0gMEwgICAgIyBib3JyYXIgbGEgbWF0cml6CiAgCiAgIy0tLS0gYnVjbGUgZGUgbG9zIGluZGl2aWR1b3MKICBmb3IoaSBpbiAxOk4pewogICAgCiAgICAjIGNvbXByb2JhciBjb252YWxlY2VuY2lhCiAgICBpZihlc3RhZG9baV0gPT0gMSkgeyMgc29sbyBwYXJhIGluZmVjdGFkb3MKICAgICAgY29udmFsW2ldIDwtIGNvbnZhbFtpXSArIDEKICAgICAgaWYoY29udmFsW2ldID4gZCkgeyMgc2UgcmVjdXBlcmEKICAgICAgICBlc3RhZG9baV0gPC0gMgogICAgICAgIEkgPC0gSSAtIDEKICAgICAgICBSIDwtIFIgKyAxCiAgICAgIH0KICAgIH0KICAgIAogICAgIyBtb3ZpbWllbnRvIGFsIGF6YXIKICAgIGR4IDwtIHNhbXBsZShtb3YsIHNpemUgPSAxLCBwcm9iID0gcG12KQogICAgZHkgPC0gc2FtcGxlKG1vdiwgc2l6ZSA9IDEsIHByb2IgPSBwbXYpCiAgICB4W2ldIDwtIHhbaV0gKyBkeAogICAgeVtpXSA8LSB5W2ldICsgZHkKICAgIGlmKHhbaV0gPiB4bWF4KSB7eFtpXSA8LSAxfSAjIHBvciBzaSBzZSBzYWxlIHBvciBsb3MgbGFkb3MKICAgIGlmKHhbaV0gPCAxKSB7eFtpXSA8LSB4bWF4fQogICAgaWYoeVtpXSA+IHltYXgpIHt5W2ldIDwtIDF9ICMgcG9yIHNpIHNlIHNhbGUgcG9yIGFycmliYS9hYmFqbwogICAgaWYoeVtpXSA8IDEpIHt5W2ldIDwtIHltYXh9CiAgICAgIAogICAgIyBkZXRlY3RhciBlbmN1ZW50cm8KICAgIG8gPC0gWFkxW3hbaV0sIHlbaV1dCiAgICBpZihvID4gMCkgewogICAgICBpZihvICE9IGkpIHsgIyBzZSBoYSBlbmNvbnRyYWRvIGNvbiBvdHJvCiAgICAgICAgIyBzZSBsbyBwZWdvCiAgICAgICAgaWYoKGVzdGFkb1tpXSA9PSAxKSAmIChlc3RhZG9bb10gPT0gMCkpewogICAgICAgICAgaWYocnVuaWYoMSkgPCBwKXsKICAgICAgICAgICAgZXN0YWRvW29dIDwtIDEKICAgICAgICAgICAgY29udmFsW29dIDwtIDAKICAgICAgICAgICAgSSA8LSBJICsgMQogICAgICAgICAgICBTIDwtIFMgLSAxCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICMgbWUgbG8gcGVnYQogICAgICAgIGlmKChlc3RhZG9bb10gPT0gMSkgJiAoZXN0YWRvW2ldID09IDApKXsKICAgICAgICAgIGlmKHJ1bmlmKDEpIDwgcCl7CiAgICAgICAgICAgIGVzdGFkb1tpXSA8LSAxCiAgICAgICAgICAgIGNvbnZhbFtpXSA8LSAwCiAgICAgICAgICAgIEkgPC0gSSArIDEKICAgICAgICAgICAgUyA8LSBTIC0gMQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogICAgCiAgICBYWVt4W2ldLCB5W2ldXSA8LSBpICAgIyBhY3R1YWxpemFyIGxvY2FsaXphY2nDs24KICB9CiAgCiAgU3RbdF0gPC0gUwogIEl0W3RdIDwtIEkgICAgIyBndWFyZGFyIHZhbG9yZXMKICBSdFt0XSA8LSBSCiAgCiAgIyBncsOhZmljbwogICMgcGxvdCh4LCB5LCB4bGltID0gYygxLCB4bWF4KSwgeWxpbSA9IGMoMSwgeW1heCksIHBjaCA9IDIwLCBjb2wgPSAzIC0gZXN0YWRvLAogICMgICAgICBtYWluID0gYnF1b3RlKHQ6Lih0KX4iICAgIn5TOi4oUyl+IiAgICJ+STouKEkpfiIgICAiflI6LihSKSksCiAgIyAgICAgIHhsYWIgPSAieCIsIHlsYWIgPSAieSIpCiAgcGxvdCh0YWJsZShjb252YWwpLCB4bGltID0gYygxLCBkKSwgeWxpbSA9IGMoMCwgNTApKQogIGFibGluZSh2ID0gbWVhbihuYS5vbWl0KGNvbnZhbFtjb252YWwgPD0gZF0pKSwgY29sID0gMikKIAp9CiAgIGFuaS5yZWNvcmQoKSAjIGdyYWJhIGNvbW8gZm90b2dyYW1hCiAgfSwgaW50ZXJ2YWwgPSAuMiwgbW92aWUubmFtZSA9ICJTX0lfUl8wMS5naWYiLCBhbmkud2lkdGggPSAyNTYsIGFuaS5oZWlnaHQgPSAyNTYpCmBgYAoKPGNlbnRlcj48dmlkZW8gd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIGNvbnRyb2xzPgogIDxzb3VyY2Ugc3JjPSJjb252Lm1wNCIgdHlwZT0idmlkZW8vbXA0Ij4KPC92aWRlbz48L2NlbnRlcj4KICA8ZmlnY2FwdGlvbj4KICAqKlbDrWRlbyAyLiBEaXN0cmlidWNpw7NuIGRlIHRpZW1wbyBkZSBjb252YWxlY2VuY2lhLioqICBDb25mb3JtZSB2YW4gZW50cmFuZG8gaW5kaXZpZHVvcyBlbiBlbCBwZXJpb2RvIGRlIGNvbnZhbGVjZW5jaWEsIHZhbiBzYWxpZW5kbyBwb3IgZWwgb3RybyBsYWRvLiAgRWwgdGllbXBvIG1lZGlvIGRlIGNvbnZhbGVjZW5jaWEgY3VtcGxpZGEgKGzDrW5lYSByb2phKSBubyBlcyBjb25zdGFudGU6IGFsIHByaW5jaXBpbyBlcyBtZW5vciB5LCBjb25mb3JtZSBhdmFuemEgZWwgdGllbXBvLCBhdW1lbnRhLiAgRXN0byBzaWduaWZpY2EgcXVlIG5vIHNlIHB1ZWRlIGNvbnNpZGVyYXIgY29uc3RhbnRlIHksIHBvciB0YW50bywgdGFtcG9jbyAkXGdhbW1hJC4KICA8L2ZpZ2NhcHRpb24+CgpgYGB7ciBjb21wYXJhY2nDs24gc2FsaWRhIGNvbnZhbGVjZW5jaWEsIGVjaG89RkFMU0V9CiMtLS0tIENvbXBhcmFjacOzbiBzYWxpZGEgY29udmFsZWNlbmNpYQpSc2FsIDwtIFJ0ClJzYWxbMV0gPC0gMApmb3IoaSBpbiAyOnQpewogIFJzYWxbaV0gPC0gUnRbaV0gLSBSdFtpLTFdIAp9CnBsb3QoUnNhbCwgdHlwZSA9ICJsIiwgbHdkID0gMiwgY29sID0gImxpZ2h0Ymx1ZSIsIHlsaW0gPSBjKDAsIDEyKSwgeGxhYiA9ICJUaWVtcG8iLCB5bGFiID0gIlJlY3VwZXJhZG9zIC8gZMOtYSIpCmxpbmVzKEl0L2QsIGx3ZCA9IDIsIGNvbCA9ICJvcmFuZ2UiKQpsZWdlbmQoInRvcHJpZ2h0IiwgYygic2ltdWxhY2nDs24gaW5kaXZpZHVvcyIsICJtb2RlbG8gZGlmZXJlbmNpYWwiKSwgbHR5ID0gYygxLCAxKSwgbHdkID0gYygyLCAyKSwgY29sID0gYygibGlnaHRibHVlIiwgIm9yYW5nZSIpLCBidHkgPSAibiIpCmBgYAogIDxmaWdjYXB0aW9uPgogICoqRmlndXJhIDEyLiBSZWN1cGVyYWNpw7NuIGRlIGluZmVjdGFkb3MuKiogIEVsIG1vZGVsbyBkaWZlcmVuY2lhbCBkaXNwZXJzYSBlbiBlbCB0aWVtcG8gbGEgYXBhcmljacOzbiBkZSByZWN1cGVyYWRvcyBhbCBjb25zaWRlcmFyIGhvbW9nw6luZW8gZWwgZ3J1cG8gZGUgaW5mZWN0YWRvcyAoY29tbyBzZSBleHBsaWPDsyBpbnR1aXRpdmFtZW50ZSBlbiBsYSBGaWd1cmEgMSkuICBFbiBlbCBWw61kZW8gMiBzZSB2ZSBjb21vIGxhIHNhbGlkYSBkZSBjb252YWxlY2VuY2lhIHNlIHByb2R1Y2Ugc2Vnw7puIHVuYSBjb2xhIHRpcG8gKkZJRk8qICrCq3ByaW1lcm8gZW4gZW50cmFyLCBwcmltZXJvIGVuIHNhbGlywrsqLiAgQ29tbyBjb25zZWN1ZW5jaWEsIGxhIG9sYSBkZSBpbmZlY3RhZG9zIHNlIGFsYXJnYSBlbiBlbCBtb2RlbG8gZGlmZXJlbmNpYWwKICA8L2ZpZ2NhcHRpb24+CgoKICBTb3JwcmVuZGVudGVtZW50ZSwgYWwgcmVzb2x2ZXIgZXN0ZSBhc3VudG8gaGVtb3MgY29tcHJvYmFkbyBxdWUgZWwgY2zDoXNpY28gbW9kZWxvICpTSVIqIGVzIHJlYWxpc3RhIGVuIGxhIHByb3BhZ2FjacOzbiBkZSBsYSBlcGlkZW1pYSB5LCBzaW4gZW1iYXJnbywgZmFsbGEgYWwgZXhwbGljYXIgZWwgZmluYWwgZGUgbGEgb2xhIHBvcnF1ZSAkXGdhbW1hJCwgZW4gcmVhbGlkYWQsIG5vIGVzIGNvbnN0YW50ZS4gIFBvciBjaWVydG8sIMK/cXXDqSB0aXBvIGRlIGZ1bmNpw7NuIHNlcsOtYT8gIMKhTm8gYWNhYmFuIGxvcyBmbGVjb3MhCgoK